mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-01-02 15:56:34 +00:00
Compare commits
13 Commits
release-20
...
v1.5.56
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df8eb399f7 | ||
|
|
3b7157714d | ||
|
|
ef7e5b4a46 | ||
|
|
c28286bf3f | ||
|
|
15e998e05d | ||
|
|
cdbdb395ac | ||
|
|
8819c12b81 | ||
|
|
a4e0971c27 | ||
|
|
726fc27331 | ||
|
|
a9d6a1221e | ||
|
|
84cc32e3b3 | ||
|
|
983c747bc3 | ||
|
|
a901d8a3ba |
2
.env
2
.env
@@ -1,2 +1,2 @@
|
||||
REGISTRY_PREFIX=harbor.sheldan.dev/abstracto/
|
||||
VERSION=1.5.51
|
||||
VERSION=1.5.55
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>anti-raid</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>anti-raid</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>assignable-roles-int</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>custom-command</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>custom-command</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>dynamic-activity</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>dynamic-activity</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>giveaway</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>giveaway-impl</artifactId>
|
||||
@@ -38,6 +38,12 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>modmail-int</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.core</groupId>
|
||||
<artifactId>metrics-int</artifactId>
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
package dev.sheldan.abstracto.giveaway.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayFeatureDefinition;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayMode;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawaySlashCommandNames;
|
||||
import dev.sheldan.abstracto.giveaway.service.management.GiveawayKeyManagementService;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class AddGiveawayKey extends AbstractConditionableCommand {
|
||||
|
||||
private static final String KEY_PARAMETER = "key";
|
||||
private static final String DESCRIPTION_PARAMETER = "description";
|
||||
private static final String BENEFACTOR_PARAMETER = "benefactor";
|
||||
private static final String NAME_PARAMETER = "name";
|
||||
private static final String ADD_GIVEAWAY_KEY_COMMAND_NAME = "addGiveawayKey";
|
||||
private static final String ADD_GIVEAWAY_KEY_RESPONSE = "addGiveawayKey_response";
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayKeyManagementService giveawayKeyManagementService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String key = slashCommandParameterService.getCommandOption(KEY_PARAMETER, event, String.class);
|
||||
String name = slashCommandParameterService.getCommandOption(NAME_PARAMETER, event, String.class);
|
||||
String description;
|
||||
if(slashCommandParameterService.hasCommandOption(DESCRIPTION_PARAMETER, event)) {
|
||||
description = slashCommandParameterService.getCommandOption(DESCRIPTION_PARAMETER, event, String.class);
|
||||
} else {
|
||||
description = null;
|
||||
}
|
||||
Member benefactor;
|
||||
if(slashCommandParameterService.hasCommandOption(BENEFACTOR_PARAMETER, event)) {
|
||||
benefactor = slashCommandParameterService.getCommandOption(BENEFACTOR_PARAMETER, event, Member.class);
|
||||
} else {
|
||||
benefactor = null;
|
||||
}
|
||||
giveawayKeyManagementService.createGiveawayKey(event.getMember(), benefactor, key, description, name);
|
||||
return interactionService.replyEmbed(ADD_GIVEAWAY_KEY_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter giveawayKey = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(KEY_PARAMETER)
|
||||
.type(String.class)
|
||||
.build();
|
||||
|
||||
Parameter giveawayKeyDescription = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(DESCRIPTION_PARAMETER)
|
||||
.type(String.class)
|
||||
.optional(true)
|
||||
.build();
|
||||
|
||||
|
||||
Parameter giveawayKeyBenefactor = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(BENEFACTOR_PARAMETER)
|
||||
.type(Member.class)
|
||||
.optional(true)
|
||||
.build();
|
||||
|
||||
Parameter giveawayKeyName = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(giveawayKeyName, giveawayKey, giveawayKeyBenefactor, giveawayKeyDescription);
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(GiveawaySlashCommandNames.GIVEAWAY)
|
||||
.groupName("keys")
|
||||
.commandName("add")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(ADD_GIVEAWAY_KEY_COMMAND_NAME)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.slashCommandOnly(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(false)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return GiveawayFeatureDefinition.GIVEAWAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FeatureMode> getFeatureModeLimitations() {
|
||||
return Arrays.asList(GiveawayMode.KEY_GIVEAWAYS);
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,7 @@ public class CancelGiveaway extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(GiveawaySlashCommandNames.GIVEAWAY)
|
||||
.groupName("management")
|
||||
.commandName("cancel")
|
||||
.build();
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import dev.sheldan.abstracto.giveaway.service.GiveawayService;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import net.dv8tion.jda.api.interactions.InteractionHook;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -25,6 +26,7 @@ import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Component
|
||||
public class GreateGiveaway extends AbstractConditionableCommand {
|
||||
@@ -48,55 +50,63 @@ public class GreateGiveaway extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private GiveawayService giveawayService;
|
||||
|
||||
@Autowired
|
||||
private GreateGiveaway self;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
return event.deferReply()
|
||||
.submit()
|
||||
.thenCompose(interactionHook -> {
|
||||
String title = slashCommandParameterService.getCommandOption(TITLE_PARAMETER, event, String.class);
|
||||
String description;
|
||||
if(slashCommandParameterService.hasCommandOption(DESCRIPTION_PARAMETER, event)) {
|
||||
description = slashCommandParameterService.getCommandOption(DESCRIPTION_PARAMETER, event, String.class);
|
||||
} else {
|
||||
description = null;
|
||||
}
|
||||
.thenCompose(interactionHook -> self.createGiveaway(event, interactionHook))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
|
||||
String durationString = slashCommandParameterService.getCommandOption(DURATION_PARAMETER, event, Duration.class, String.class);
|
||||
Duration duration = ParseUtils.parseDuration(durationString);
|
||||
}
|
||||
|
||||
GuildMessageChannel target = null;
|
||||
if(slashCommandParameterService.hasCommandOption(CHANNEL_PARAMETER, event)) {
|
||||
target = slashCommandParameterService.getCommandOption(CHANNEL_PARAMETER, event, GuildMessageChannel.class);
|
||||
}
|
||||
@Transactional
|
||||
public CompletableFuture<Void> createGiveaway(SlashCommandInteractionEvent event, InteractionHook interactionHook) {
|
||||
String title = slashCommandParameterService.getCommandOption(TITLE_PARAMETER, event, String.class);
|
||||
String description;
|
||||
if(slashCommandParameterService.hasCommandOption(DESCRIPTION_PARAMETER, event)) {
|
||||
description = slashCommandParameterService.getCommandOption(DESCRIPTION_PARAMETER, event, String.class);
|
||||
} else {
|
||||
description = null;
|
||||
}
|
||||
|
||||
Integer winners = 1;
|
||||
if(slashCommandParameterService.hasCommandOption(WINNERS_PARAMETER, event)) {
|
||||
winners = slashCommandParameterService.getCommandOption(WINNERS_PARAMETER, event, Integer.class);
|
||||
}
|
||||
String durationString = slashCommandParameterService.getCommandOption(DURATION_PARAMETER, event, Duration.class, String.class);
|
||||
Duration duration = ParseUtils.parseDuration(durationString);
|
||||
|
||||
Member benefactor;
|
||||
if(slashCommandParameterService.hasCommandOption(BENEFACTOR_PARAMETER, event)) {
|
||||
benefactor = slashCommandParameterService.getCommandOption(BENEFACTOR_PARAMETER, event, Member.class);
|
||||
} else {
|
||||
benefactor = null;
|
||||
}
|
||||
GuildMessageChannel target = null;
|
||||
if(slashCommandParameterService.hasCommandOption(CHANNEL_PARAMETER, event)) {
|
||||
target = slashCommandParameterService.getCommandOption(CHANNEL_PARAMETER, event, GuildMessageChannel.class);
|
||||
}
|
||||
|
||||
Member creator = event.getMember();
|
||||
GiveawayCreationRequest request = GiveawayCreationRequest
|
||||
.builder()
|
||||
.benefactor(benefactor)
|
||||
.creator(creator)
|
||||
.description(description)
|
||||
.duration(duration)
|
||||
.targetChannel(target)
|
||||
.winnerCount(winners)
|
||||
.title(title)
|
||||
.build();
|
||||
Integer winners = 1;
|
||||
if(slashCommandParameterService.hasCommandOption(WINNERS_PARAMETER, event)) {
|
||||
winners = slashCommandParameterService.getCommandOption(WINNERS_PARAMETER, event, Integer.class);
|
||||
}
|
||||
|
||||
return giveawayService.createGiveaway(request)
|
||||
.thenAccept(unused -> interactionService.sendEmbed(CREATE_GIVEAWAY_RESPONSE_TEMPLATE_KEY, interactionHook));
|
||||
}).thenApply(unused -> CommandResult.fromSuccess());
|
||||
Member benefactor;
|
||||
if(slashCommandParameterService.hasCommandOption(BENEFACTOR_PARAMETER, event)) {
|
||||
benefactor = slashCommandParameterService.getCommandOption(BENEFACTOR_PARAMETER, event, Member.class);
|
||||
} else {
|
||||
benefactor = null;
|
||||
}
|
||||
|
||||
Member creator = event.getMember();
|
||||
GiveawayCreationRequest request = GiveawayCreationRequest
|
||||
.builder()
|
||||
.benefactorId(benefactor != null ? benefactor.getIdLong() : null)
|
||||
.creatorId(creator.getIdLong())
|
||||
.description(description)
|
||||
.duration(duration)
|
||||
.targetChannel(target)
|
||||
.winnerCount(winners)
|
||||
.serverId(creator.getGuild().getIdLong())
|
||||
.title(title)
|
||||
.build();
|
||||
|
||||
return giveawayService.createGiveaway(request)
|
||||
.thenAccept(unused -> interactionService.sendEmbed(CREATE_GIVEAWAY_RESPONSE_TEMPLATE_KEY, interactionHook));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -159,6 +169,7 @@ public class GreateGiveaway extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(GiveawaySlashCommandNames.GIVEAWAY)
|
||||
.groupName("management")
|
||||
.commandName("create")
|
||||
.build();
|
||||
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
package dev.sheldan.abstracto.giveaway.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import dev.sheldan.abstracto.core.utils.ParseUtils;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayFeatureConfig;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayFeatureDefinition;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayMode;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawaySlashCommandNames;
|
||||
import dev.sheldan.abstracto.giveaway.exception.GiveawayNotPossibleException;
|
||||
import dev.sheldan.abstracto.giveaway.exception.GiveawayKeyNotFoundException;
|
||||
import dev.sheldan.abstracto.giveaway.model.GiveawayCreationRequest;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.GiveawayKey;
|
||||
import dev.sheldan.abstracto.giveaway.service.GiveawayService;
|
||||
import dev.sheldan.abstracto.giveaway.service.management.GiveawayKeyManagementService;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import net.dv8tion.jda.api.interactions.InteractionHook;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Component
|
||||
public class GreateKeyGiveaway extends AbstractConditionableCommand {
|
||||
|
||||
private static final String COMMAND_NAME = "createKeyGiveaway";
|
||||
private static final String KEY_ID_PARAMETER = "keyId";
|
||||
private static final String DURATION_PARAMETER = "duration";
|
||||
|
||||
private static final String CREATE_KEY_GIVEAWAY_RESPONSE_TEMPLATE_KEY = "createKeyGiveaway_response";
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayService giveawayService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayKeyManagementService giveawayKeyManagementService;
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private GreateKeyGiveaway self;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
Long id = slashCommandParameterService.getCommandOption(KEY_ID_PARAMETER, event, Integer.class).longValue();
|
||||
String durationString;
|
||||
if(slashCommandParameterService.hasCommandOption(DURATION_PARAMETER, event)) {
|
||||
durationString = slashCommandParameterService.getCommandOption(DURATION_PARAMETER, event, Duration.class, String.class);
|
||||
} else {
|
||||
durationString = configService.getStringValueOrConfigDefault(GiveawayFeatureConfig.KEY_GIVEAWAYS_DURATION, event.getGuild().getIdLong()).trim();
|
||||
}
|
||||
Duration duration = ParseUtils.parseDuration(durationString);
|
||||
return event.deferReply()
|
||||
.submit()
|
||||
.thenCompose(interactionHook -> self.createKeyGiveaway(id, interactionHook, duration))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> createKeyGiveaway(Long giveawayKeyId, InteractionHook interactionHook, Duration duration) {
|
||||
Long serverId = interactionHook.getInteraction().getGuild().getIdLong();
|
||||
GiveawayKey giveawayKey = giveawayKeyManagementService.getById(giveawayKeyId, serverId)
|
||||
.orElseThrow(GiveawayKeyNotFoundException::new);
|
||||
if((giveawayKey.getGiveaway() != null && giveawayKey.getGiveaway().getTargetDate().isAfter(Instant.now())) || giveawayKey.getUsed()) {
|
||||
throw new GiveawayNotPossibleException();
|
||||
}
|
||||
GiveawayCreationRequest request = GiveawayCreationRequest
|
||||
.builder()
|
||||
.benefactorId(giveawayKey.getBenefactor() != null ? giveawayKey.getBenefactor().getUserReference().getId() : null)
|
||||
.creatorId(giveawayKey.getCreator().getUserReference().getId())
|
||||
.description(giveawayKey.getDescription())
|
||||
.duration(duration)
|
||||
.serverId(serverId)
|
||||
.giveawayKeyId(giveawayKeyId)
|
||||
.winnerCount(1)
|
||||
.title(giveawayKey.getName())
|
||||
.build();
|
||||
|
||||
return giveawayService.createGiveaway(request)
|
||||
.thenAccept(giveawayId -> {
|
||||
interactionService.sendEmbed(CREATE_KEY_GIVEAWAY_RESPONSE_TEMPLATE_KEY, interactionHook);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter keyParameter = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(KEY_ID_PARAMETER)
|
||||
.type(Long.class)
|
||||
.build();
|
||||
|
||||
Parameter durationParameter = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(DURATION_PARAMETER)
|
||||
.optional(true)
|
||||
.type(Duration.class)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(keyParameter, durationParameter);
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(GiveawaySlashCommandNames.GIVEAWAY)
|
||||
.groupName("key")
|
||||
.commandName("creategiveaway")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(COMMAND_NAME)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(false)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return GiveawayFeatureDefinition.GIVEAWAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FeatureMode> getFeatureModeLimitations() {
|
||||
return Arrays.asList(GiveawayMode.KEY_GIVEAWAYS);
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,7 @@ public class ReRollGiveaway extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(GiveawaySlashCommandNames.GIVEAWAY)
|
||||
.groupName("management")
|
||||
.commandName("reroll")
|
||||
.build();
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package dev.sheldan.abstracto.giveaway.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayFeatureDefinition;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayMode;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawaySlashCommandNames;
|
||||
import dev.sheldan.abstracto.giveaway.service.management.GiveawayKeyManagementService;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class RemoveGiveawayKey extends AbstractConditionableCommand {
|
||||
|
||||
|
||||
private static final String ID_PARAMETER = "id";
|
||||
private static final String REMOVE_GIVEAWAY_KEY_COMMAND_NAME = "removeGiveawayKey";
|
||||
private static final String REMOVE_GIVEAWAY_KEY_RESPONSE = "removeGiveawayKey_response";
|
||||
|
||||
@Autowired
|
||||
private GiveawayKeyManagementService giveawayKeyManagementService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
Long id = slashCommandParameterService.getCommandOption(ID_PARAMETER, event, Integer.class).longValue();
|
||||
giveawayKeyManagementService.deleteById(id, event.getGuild().getIdLong());
|
||||
return interactionService.replyEmbed(REMOVE_GIVEAWAY_KEY_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter giveawayKeyId = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(ID_PARAMETER)
|
||||
.type(Long.class)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(giveawayKeyId);
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(GiveawaySlashCommandNames.GIVEAWAY)
|
||||
.groupName("keys")
|
||||
.commandName("remove")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(REMOVE_GIVEAWAY_KEY_COMMAND_NAME)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.slashCommandOnly(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(false)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return GiveawayFeatureDefinition.GIVEAWAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FeatureMode> getFeatureModeLimitations() {
|
||||
return Arrays.asList(GiveawayMode.KEY_GIVEAWAYS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package dev.sheldan.abstracto.giveaway.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.service.PaginatorService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayFeatureDefinition;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayMode;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawaySlashCommandNames;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.GiveawayKey;
|
||||
import dev.sheldan.abstracto.giveaway.model.template.GiveawayKeyDisplayModel;
|
||||
import dev.sheldan.abstracto.giveaway.model.template.GiveawayKeysDisplayModel;
|
||||
import dev.sheldan.abstracto.giveaway.service.management.GiveawayKeyManagementService;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ShowGiveawayKeys extends AbstractConditionableCommand {
|
||||
|
||||
public static final String SHOW_ALL_PARAMETER_NAME = "all";
|
||||
|
||||
|
||||
private static final String SHOW_GIVEAWAY_KEYS_RESPONSE_TEMPLATE = "showGiveawayKeys_response";
|
||||
private static final String SHOW_GIVEAWAY_NO_KEYS_FOUND_TEMPLATE = "showGiveawayKeys_no_keys_found";
|
||||
|
||||
@Autowired
|
||||
private PaginatorService paginatorService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayKeyManagementService giveawayKeyManagementService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
boolean showAll;
|
||||
if(slashCommandParameterService.hasCommandOption(SHOW_ALL_PARAMETER_NAME, event)) {
|
||||
showAll = slashCommandParameterService.getCommandOption(SHOW_ALL_PARAMETER_NAME, event, Boolean.class);
|
||||
} else {
|
||||
showAll = false;
|
||||
}
|
||||
List<GiveawayKey> giveawayKeys = giveawayKeyManagementService.getGiveawayKeys(event.getGuild().getIdLong(), showAll);
|
||||
if(giveawayKeys.isEmpty()) {
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(SHOW_GIVEAWAY_NO_KEYS_FOUND_TEMPLATE, new Object(), event.getGuild().getIdLong());
|
||||
return interactionService.replyMessageToSend(messageToSend, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
List<GiveawayKeyDisplayModel> models = giveawayKeys
|
||||
.stream()
|
||||
.map(giveawayKey -> GiveawayKeyDisplayModel
|
||||
.builder()
|
||||
.key(giveawayKey.getKey())
|
||||
.id(giveawayKey.getId().getKeyId())
|
||||
.used(giveawayKey.getUsed())
|
||||
.description(giveawayKey.getDescription())
|
||||
.name(giveawayKey.getName())
|
||||
.winner(giveawayKey.getWinner() != null ? MemberDisplay.fromAUserInAServer(giveawayKey.getWinner()) : null)
|
||||
.creator(MemberDisplay.fromAUserInAServer(giveawayKey.getCreator()))
|
||||
.benefactor(giveawayKey.getBenefactor() != null ? MemberDisplay.fromAUserInAServer(giveawayKey.getBenefactor()) : null)
|
||||
.build())
|
||||
.toList();
|
||||
GiveawayKeysDisplayModel model = GiveawayKeysDisplayModel
|
||||
.builder()
|
||||
.keys(models)
|
||||
.build();
|
||||
return paginatorService.createPaginatorFromTemplate(SHOW_GIVEAWAY_KEYS_RESPONSE_TEMPLATE, model, event)
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
|
||||
Parameter showAllParameter = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(SHOW_ALL_PARAMETER_NAME)
|
||||
.type(Boolean.class)
|
||||
.optional(true)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(showAllParameter);
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(GiveawaySlashCommandNames.GIVEAWAY)
|
||||
.groupName("keys")
|
||||
.commandName("show")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("showGiveawayKeys")
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.async(true)
|
||||
.slashCommandOnly(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(false)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return GiveawayFeatureDefinition.GIVEAWAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FeatureMode> getFeatureModeLimitations() {
|
||||
return Arrays.asList(GiveawayMode.KEY_GIVEAWAYS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.abstracto.giveaway.repository;
|
||||
|
||||
import dev.sheldan.abstracto.giveaway.model.database.GiveawayKey;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.embed.GiveawayKeyId;
|
||||
import java.util.List;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface GiveawayKeyRepository extends JpaRepository<GiveawayKey, GiveawayKeyId> {
|
||||
List<GiveawayKey> findGiveawayKeysByUsedAndServer_IdOrderById(Boolean used, Long serverId);
|
||||
List<GiveawayKey> findGiveawayKeysByServer_IdOrderById(Long serverId);
|
||||
}
|
||||
@@ -7,28 +7,38 @@ import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.CounterService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.core.service.UserService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayFeatureDefinition;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayMode;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayPostTarget;
|
||||
import dev.sheldan.abstracto.giveaway.exception.GiveawayKeyNotFoundException;
|
||||
import dev.sheldan.abstracto.giveaway.exception.GiveawayNotFoundException;
|
||||
import dev.sheldan.abstracto.giveaway.model.GiveawayCreationRequest;
|
||||
import dev.sheldan.abstracto.giveaway.model.JoinGiveawayPayload;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.Giveaway;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.GiveawayKey;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.GiveawayParticipant;
|
||||
import dev.sheldan.abstracto.giveaway.model.template.GiveawayMessageModel;
|
||||
import dev.sheldan.abstracto.giveaway.model.template.GiveawayResultMessageModel;
|
||||
import dev.sheldan.abstracto.giveaway.model.template.GiveawayWinnerNotificationMessageModel;
|
||||
import dev.sheldan.abstracto.giveaway.service.management.GiveawayKeyManagementService;
|
||||
import dev.sheldan.abstracto.giveaway.service.management.GiveawayManagementService;
|
||||
import dev.sheldan.abstracto.giveaway.service.management.GiveawayParticipantManagementService;
|
||||
import dev.sheldan.abstracto.modmail.service.ModMailThreadService;
|
||||
import dev.sheldan.abstracto.scheduling.model.JobParameters;
|
||||
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
|
||||
import jakarta.transaction.Transactional;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -44,6 +54,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
public class GiveawayServiceBean implements GiveawayService {
|
||||
|
||||
private static final String GIVEAWAY_MESSAGE_TEMPLATE_KEY = "giveaway_post";
|
||||
private static final String GIVEAWAY_WINNER_MODMAIL_NOTIFICATION = "giveaway_winner_modmail_notification";
|
||||
private static final String GIVEAWAY_RESULT_MESSAGE_TEMPLATE_KEY = "giveaway_result";
|
||||
public static final String GIVEAWAY_JOIN_ORIGIN = "JOIN_GIVEAWAY";
|
||||
|
||||
@@ -85,42 +96,55 @@ public class GiveawayServiceBean implements GiveawayService {
|
||||
@Autowired
|
||||
private CounterService counterService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayKeyManagementService giveawayKeyManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private ModMailThreadService modMailThreadService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayServiceBean self;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> createGiveaway(GiveawayCreationRequest giveawayCreationRequest) {
|
||||
public CompletableFuture<Long> createGiveaway(GiveawayCreationRequest giveawayCreationRequest) {
|
||||
String componentId = componentService.generateComponentId();
|
||||
Instant targetDate = Instant.now().plus(giveawayCreationRequest.getDuration());
|
||||
Long serverId = giveawayCreationRequest.getCreator().getGuild().getIdLong();
|
||||
Long serverId = giveawayCreationRequest.getServerId();
|
||||
Long giveawayId = counterService.getNextCounterValue(serverId, GIVEAWAY_COUNTER);
|
||||
GiveawayMessageModel model = GiveawayMessageModel
|
||||
.builder()
|
||||
.title(giveawayCreationRequest.getTitle())
|
||||
.description(giveawayCreationRequest.getDescription())
|
||||
.giveawayId(giveawayId)
|
||||
.benefactor(giveawayCreationRequest.getBenefactor() != null ? MemberDisplay.fromMember(giveawayCreationRequest.getBenefactor()) : null)
|
||||
.creator(MemberDisplay.fromMember(giveawayCreationRequest.getCreator()))
|
||||
.benefactor(giveawayCreationRequest.getBenefactorId() != null ? MemberDisplay.fromIds(giveawayCreationRequest.getServerId(), giveawayCreationRequest.getBenefactorId()) : null)
|
||||
.creator(MemberDisplay.fromIds(giveawayCreationRequest.getServerId(), giveawayCreationRequest.getCreatorId()))
|
||||
.winnerCount(giveawayCreationRequest.getWinnerCount())
|
||||
.targetDate(targetDate)
|
||||
.joinComponentId(componentId)
|
||||
.build();
|
||||
List<CompletableFuture<Message>> messageFutures;
|
||||
log.info("Rendering giveaway message in server {} by user {}", serverId, giveawayCreationRequest.getCreator().getIdLong());
|
||||
log.info("Rendering giveaway message in server {} by user {}", serverId, giveawayCreationRequest.getCreatorId());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(GIVEAWAY_MESSAGE_TEMPLATE_KEY, model, serverId);
|
||||
if(giveawayCreationRequest.getTargetChannel() == null) {
|
||||
log.info("Sending giveaway to post target in server {}", serverId);
|
||||
postTargetService.validatePostTarget(GiveawayPostTarget.GIVEAWAYS, giveawayCreationRequest.getCreator().getGuild().getIdLong());
|
||||
postTargetService.validatePostTarget(GiveawayPostTarget.GIVEAWAYS, serverId);
|
||||
messageFutures = postTargetService.sendEmbedInPostTarget(messageToSend, GiveawayPostTarget.GIVEAWAYS, serverId);
|
||||
} else {
|
||||
log.info("Sending giveaway to channel {} in server {}.", giveawayCreationRequest.getTargetChannel().getId(), serverId);
|
||||
messageFutures = channelService.sendMessageToSendToChannel(messageToSend, giveawayCreationRequest.getTargetChannel());
|
||||
}
|
||||
CompletableFutureList<Message> messageFutureList = new CompletableFutureList<>(messageFutures);
|
||||
return messageFutureList.getMainFuture().thenAccept(o -> {
|
||||
return messageFutureList.getMainFuture().thenApply(o -> {
|
||||
Message createdMessage = messageFutureList.getFutures().get(0).join();
|
||||
giveawayCreationRequest.setTargetChannel(createdMessage.getGuildChannel());
|
||||
self.persistGiveaway(giveawayCreationRequest, giveawayId, createdMessage.getIdLong(), componentId);
|
||||
return giveawayId;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -140,13 +164,9 @@ public class GiveawayServiceBean implements GiveawayService {
|
||||
@Override
|
||||
@Transactional
|
||||
public CompletableFuture<Void> evaluateGiveaway(Long giveawayId, Long serverId) {
|
||||
Optional<Giveaway> giveAwayOptional = giveawayManagementService.loadGiveawayById(giveawayId, serverId);
|
||||
if(giveAwayOptional.isEmpty()) {
|
||||
throw new GiveawayNotFoundException();
|
||||
}
|
||||
Giveaway giveaway = giveawayManagementService.loadGiveawayById(giveawayId, serverId).orElseThrow(GiveawayNotFoundException::new);
|
||||
log.info("Evaluating giveaway {} in server {}.", giveawayId, serverId);
|
||||
Giveaway giveaway = giveAwayOptional.get();
|
||||
Set<Long> winners = new HashSet<>();
|
||||
Set<Long> winnerUserInServerIds = new HashSet<>();
|
||||
Integer winnerCount = giveaway.getWinnerCount();
|
||||
giveaway.getParticipants().forEach(giveawayParticipant -> giveawayParticipant.setWon(false));
|
||||
List<Long> potentialWinners = new ArrayList<>(giveaway
|
||||
@@ -156,20 +176,20 @@ public class GiveawayServiceBean implements GiveawayService {
|
||||
.toList());
|
||||
|
||||
if(potentialWinners.size() <= winnerCount) {
|
||||
winners.addAll(potentialWinners);
|
||||
winnerUserInServerIds.addAll(potentialWinners);
|
||||
log.debug("Less participants than total winners - selecting all for giveaway {} in server {}.", giveawayId, serverId);
|
||||
} else {
|
||||
for (int i = 0; i < winnerCount; i++) {
|
||||
int winnerIndex = secureRandom.nextInt(potentialWinners.size());
|
||||
Long winner = potentialWinners.get(winnerIndex);
|
||||
potentialWinners.remove(winnerIndex);
|
||||
winners.add(winner);
|
||||
winnerUserInServerIds.add(winner);
|
||||
}
|
||||
}
|
||||
List<GiveawayParticipant> winningParticipants = giveaway
|
||||
.getParticipants()
|
||||
.stream()
|
||||
.filter(giveawayParticipant -> winners.contains(giveawayParticipant.getParticipant().getUserInServerId()))
|
||||
.filter(giveawayParticipant -> winnerUserInServerIds.contains(giveawayParticipant.getParticipant().getUserInServerId()))
|
||||
.toList();
|
||||
winningParticipants.forEach(giveawayParticipant -> giveawayParticipant.setWon(true));
|
||||
List<MemberDisplay> winnerDisplays = winningParticipants
|
||||
@@ -185,16 +205,55 @@ public class GiveawayServiceBean implements GiveawayService {
|
||||
log.info("Sending result message for giveaway {} in server {}.", giveawayId, serverId);
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(GIVEAWAY_RESULT_MESSAGE_TEMPLATE_KEY, resultModel, serverId);
|
||||
List<CompletableFuture<Message>> resultFutures = channelService.sendMessageEmbedToSendToAChannel(messageToSend, giveaway.getGiveawayChannel());
|
||||
|
||||
long actualWinnerCount = winnerUserInServerIds.size();
|
||||
Long winnerUserId;
|
||||
if(giveaway.getGiveawayKey() != null && !winningParticipants.isEmpty()) {
|
||||
GiveawayParticipant winnerParticipant = winningParticipants.get(0);
|
||||
GiveawayKey giveawayKey = giveaway.getGiveawayKey();
|
||||
giveawayKey.setWinner(winnerParticipant.getParticipant());
|
||||
giveawayKey.setUsed(true);
|
||||
winnerUserId = winnerParticipant.getParticipant().getUserReference().getId();
|
||||
} else {
|
||||
winnerUserId = null;
|
||||
}
|
||||
GiveawayMessageModel giveawayMessageModel = GiveawayMessageModel.fromGiveaway(giveaway);
|
||||
giveawayMessageModel.setWinners(winnerDisplays);
|
||||
giveawayMessageModel.setEnded(true);
|
||||
boolean createGiveawayKeyNotification = giveaway.getGiveawayKey() != null
|
||||
&& featureModeService.featureModeActive(GiveawayFeatureDefinition.GIVEAWAY, serverId, GiveawayMode.AUTO_NOTIFY_GIVEAWAY_KEY_WINNERS)
|
||||
&& featureModeService.featureModeActive(GiveawayFeatureDefinition.GIVEAWAY, serverId, GiveawayMode.KEY_GIVEAWAYS)
|
||||
&& actualWinnerCount > 0
|
||||
&& modMailThreadService != null;
|
||||
MessageToSend giveawayMessageToSend = templateService.renderEmbedTemplate(GIVEAWAY_MESSAGE_TEMPLATE_KEY, giveawayMessageModel, serverId);
|
||||
log.info("Updating original giveaway message for giveaway {} in server {}.", giveawayId, serverId);
|
||||
GuildMessageChannel messageChannel = channelService.getMessageChannelFromServer(giveaway.getServer().getId(), giveaway.getGiveawayChannel().getId());
|
||||
CompletableFuture<Message> giveawayUpdateFuture = channelService.editMessageInAChannelFuture(giveawayMessageToSend, messageChannel, giveaway.getMessageId());
|
||||
resultFutures.add(giveawayUpdateFuture);
|
||||
return new CompletableFutureList<>(resultFutures).getMainFuture();
|
||||
return new CompletableFutureList<>(resultFutures).getMainFuture().thenCompose(unused -> {
|
||||
if(createGiveawayKeyNotification) {
|
||||
return userService.retrieveUserForId(winnerUserId)
|
||||
.thenCompose(user -> self.handleKeyGiveawayNotifications(giveawayId, serverId, winnerUserInServerIds.iterator().next(), user))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to notify winner of giveaway {} in server {}.", giveawayId, serverId, throwable);
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> handleKeyGiveawayNotifications(Long giveawayId, Long serverId, Long winnerInServerId, User user) {
|
||||
if(modMailThreadService == null) {
|
||||
log.info("Modmail service not available - skipping notifications about giveaway {} in server {}.", giveawayId, serverId);
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
Giveaway giveaway = giveawayManagementService.loadGiveawayById(giveawayId, serverId).orElseThrow(GiveawayNotFoundException::new);
|
||||
GiveawayWinnerNotificationMessageModel messageModel = GiveawayWinnerNotificationMessageModel.fromGiveaway(giveaway, giveaway.getGiveawayKey().getKey());
|
||||
AUserInAServer winner = userInServerManagementService.loadOrCreateUser(winnerInServerId);
|
||||
MessageToSend giveawayWinnerNotification = templateService.renderEmbedTemplate(GIVEAWAY_WINNER_MODMAIL_NOTIFICATION, messageModel, serverId);
|
||||
return modMailThreadService.sendMessageToUser(winner, giveawayWinnerNotification, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -241,14 +300,13 @@ public class GiveawayServiceBean implements GiveawayService {
|
||||
|
||||
@Transactional
|
||||
public void persistGiveaway(GiveawayCreationRequest giveawayCreationRequest, Long giveawayId, Long messageId, String componentId) {
|
||||
Member creatorMember = giveawayCreationRequest.getCreator();
|
||||
log.info("Persisting giveaway in server {} with message id {}.", creatorMember.getGuild().getIdLong(), messageId);
|
||||
log.info("Persisting giveaway in server {} with message id {}.", giveawayCreationRequest.getServerId(), messageId);
|
||||
Instant targetDate = Instant.now().plus(giveawayCreationRequest.getDuration());
|
||||
AChannel targetChannel = channelManagementService.loadChannel(giveawayCreationRequest.getTargetChannel().getIdLong());
|
||||
AUserInAServer creator = userInServerManagementService.loadOrCreateUser(creatorMember);
|
||||
AUserInAServer creator = userInServerManagementService.loadOrCreateUser(giveawayCreationRequest.getServerId(), giveawayCreationRequest.getCreatorId());
|
||||
AUserInAServer benefactor;
|
||||
if(giveawayCreationRequest.getBenefactor() != null) {
|
||||
benefactor = userInServerManagementService.loadOrCreateUser(giveawayCreationRequest.getBenefactor());
|
||||
if(giveawayCreationRequest.getBenefactorId() != null) {
|
||||
benefactor = userInServerManagementService.loadOrCreateUser(giveawayCreationRequest.getServerId(), giveawayCreationRequest.getBenefactorId());
|
||||
} else {
|
||||
benefactor = null;
|
||||
}
|
||||
@@ -257,6 +315,12 @@ public class GiveawayServiceBean implements GiveawayService {
|
||||
giveawayCreationRequest.getTitle(), giveawayCreationRequest.getDescription(), giveawayCreationRequest.getWinnerCount(),
|
||||
messageId, componentId, giveawayId);
|
||||
|
||||
if(giveawayCreationRequest.getGiveawayKeyId() != null) {
|
||||
GiveawayKey giveawayKey = giveawayKeyManagementService.getById(giveawayCreationRequest.getGiveawayKeyId(), giveawayCreationRequest.getServerId())
|
||||
.orElseThrow(GiveawayKeyNotFoundException::new);
|
||||
giveawayKey.setGiveaway(giveaway);
|
||||
giveawayKeyManagementService.saveGiveawayKey(giveawayKey);
|
||||
}
|
||||
HashMap<Object, Object> parameters = new HashMap<>();
|
||||
parameters.put("giveawayId", giveaway.getGiveawayId().getId().toString());
|
||||
parameters.put("serverId", giveaway.getGiveawayId().getServerId().toString());
|
||||
@@ -264,7 +328,7 @@ public class GiveawayServiceBean implements GiveawayService {
|
||||
.builder()
|
||||
.parameters(parameters)
|
||||
.build();
|
||||
log.info("Scheduling giveaway reminder for giveaway {} originating from message {} in server {}.", giveaway.getGiveawayId().getId(), messageId, creatorMember.getGuild().getIdLong());
|
||||
log.info("Scheduling giveaway reminder for giveaway {} originating from message {} in server {}.", giveaway.getGiveawayId().getId(), messageId, giveawayCreationRequest.getServerId());
|
||||
String triggerKey = schedulerService.executeJobWithParametersOnce("giveawayEvaluationJob", "giveaway", jobParameters, Date.from(giveaway.getTargetDate()));
|
||||
giveaway.setReminderTriggerKey(triggerKey);
|
||||
JoinGiveawayPayload joinPayload = JoinGiveawayPayload
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package dev.sheldan.abstracto.giveaway.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.CounterService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.giveaway.exception.GiveawayKeyNotFoundException;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.GiveawayKey;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.embed.GiveawayKeyId;
|
||||
import dev.sheldan.abstracto.giveaway.repository.GiveawayKeyRepository;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class GiveawayKeyManagementServiceBean implements GiveawayKeyManagementService {
|
||||
|
||||
@Autowired
|
||||
private GiveawayKeyRepository giveawayKeyRepository;
|
||||
|
||||
@Autowired
|
||||
private CounterService counterService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
public static final String GIVEAWAY_KEYS_COUNTER = "giveaway_keys";
|
||||
|
||||
@Override
|
||||
public GiveawayKey createGiveawayKey(Member creator, Member benefactor, String key, String description, String name) {
|
||||
Long counterValue = counterService.getNextCounterValue(creator.getGuild().getIdLong(), GIVEAWAY_KEYS_COUNTER);
|
||||
GiveawayKeyId id = new GiveawayKeyId(counterValue, creator.getGuild().getIdLong());
|
||||
|
||||
AUserInAServer creatorUser = userInServerManagementService.loadOrCreateUser(creator);
|
||||
AUserInAServer benefactorUser;
|
||||
if(benefactor != null) {
|
||||
benefactorUser = userInServerManagementService.loadOrCreateUser(benefactor);
|
||||
} else {
|
||||
benefactorUser = null;
|
||||
}
|
||||
|
||||
GiveawayKey giveawayKey = GiveawayKey
|
||||
.builder()
|
||||
.id(id)
|
||||
.creator(creatorUser)
|
||||
.used(false)
|
||||
.server(creatorUser.getServerReference())
|
||||
.key(key)
|
||||
.description(description)
|
||||
.benefactor(benefactorUser)
|
||||
.name(name)
|
||||
.build();
|
||||
return giveawayKeyRepository.save(giveawayKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(Long id, Long serverId) {
|
||||
GiveawayKey key = giveawayKeyRepository.findById(new GiveawayKeyId(id, serverId)).orElseThrow(GiveawayKeyNotFoundException::new);
|
||||
key.getGiveaway().setGiveawayKey(null);
|
||||
giveawayKeyRepository.delete(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<GiveawayKey> getById(Long id, Long serverId) {
|
||||
return giveawayKeyRepository.findById(new GiveawayKeyId(id, serverId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public GiveawayKey saveGiveawayKey(GiveawayKey giveawayKey) {
|
||||
return giveawayKeyRepository.save(giveawayKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GiveawayKey> getGiveawayKeys(Long serverId, Boolean showAll) {
|
||||
if(showAll) {
|
||||
return giveawayKeyRepository.findGiveawayKeysByServer_IdOrderById(serverId);
|
||||
} else {
|
||||
return giveawayKeyRepository.findGiveawayKeysByUsedAndServer_IdOrderById(false, serverId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,15 @@
|
||||
abstracto.featureFlags.giveaway.featureName=giveaway
|
||||
abstracto.featureFlags.giveaway.enabled=false
|
||||
|
||||
abstracto.postTargets.giveaways.name=giveaways
|
||||
abstracto.postTargets.giveaways.name=giveaways
|
||||
|
||||
abstracto.featureModes.keyGiveaways.featureName=giveaway
|
||||
abstracto.featureModes.keyGiveaways.mode=keyGiveaways
|
||||
abstracto.featureModes.keyGiveaways.enabled=false
|
||||
|
||||
abstracto.featureModes.autoNotifyGiveawayKeyWinners.featureName=giveaway
|
||||
abstracto.featureModes.autoNotifyGiveawayKeyWinners.mode=autoNotifyGiveawayKeyWinners
|
||||
abstracto.featureModes.autoNotifyGiveawayKeyWinners.enabled=false
|
||||
|
||||
abstracto.systemConfigs.keyGiveawaysDuration.name=keyGiveawaysDuration
|
||||
abstracto.systemConfigs.keyGiveawaysDuration.stringValue=24h
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
|
||||
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<property name="utilityModule" value="(SELECT id FROM module WHERE name = 'utility')"/>
|
||||
<property name="giveawayFeature" value="(SELECT id FROM feature WHERE key = 'giveaway')"/>
|
||||
<changeSet author="Sheldan" id="giveawayKey-commands">
|
||||
<insert tableName="command">
|
||||
<column name="name" value="addGiveawayKey"/>
|
||||
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||
<column name="feature_id" valueComputed="${giveawayFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="removeGiveawayKey"/>
|
||||
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||
<column name="feature_id" valueComputed="${giveawayFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="showGiveawayKeys"/>
|
||||
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||
<column name="feature_id" valueComputed="${giveawayFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="createKeyGiveaway"/>
|
||||
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||
<column name="feature_id" valueComputed="${giveawayFeature}"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="command.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<changeSet author="Sheldan" id="giveaway_key-table">
|
||||
<createTable tableName="giveaway_key">
|
||||
<column name="id" type="BIGINT">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="creator_user_id" type="INTEGER">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="benefactor_user_id" type="INTEGER">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="winner_user_id" type="INTEGER">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="key" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="name" type="VARCHAR(100)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="description" type="VARCHAR(255)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="used" type="BOOLEAN">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="server_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="giveaway_id" type="BIGINT">
|
||||
<constraints nullable="true" />
|
||||
</column>
|
||||
<column name="giveaway_server_id" type="BIGINT">
|
||||
<constraints nullable="true" />
|
||||
</column>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
<addPrimaryKey tableName="giveaway_key" columnNames="id, server_id"/>
|
||||
<addForeignKeyConstraint baseColumnNames="creator_user_id" baseTableName="giveaway_key" constraintName="fk_giveaway_key_creator" deferrable="false"
|
||||
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id"
|
||||
referencedTableName="user_in_server" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="benefactor_user_id" baseTableName="giveaway_key" constraintName="fk_giveaway_key_benefactor" deferrable="false"
|
||||
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id"
|
||||
referencedTableName="user_in_server" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="winner_user_id" baseTableName="giveaway_key" constraintName="fk_giveaway_key_winner" deferrable="false"
|
||||
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id"
|
||||
referencedTableName="user_in_server" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="giveaway_id,giveaway_server_id" baseTableName="giveaway_key" constraintName="fk_giveaway_key_giveaway" deferrable="false"
|
||||
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id,server_id"
|
||||
referencedTableName="giveaway" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="giveaway_key" constraintName="fk_giveaway_key_server" deferrable="false" initiallyDeferred="false"
|
||||
onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS giveaway_key_update_trigger ON giveaway_key;
|
||||
CREATE TRIGGER giveaway_update_trigger BEFORE UPDATE ON giveaway_key FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS giveaway_key_insert_trigger ON giveaway_key;
|
||||
CREATE TRIGGER giveaway_insert_trigger BEFORE INSERT ON giveaway_key FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="giveaway_key.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -3,4 +3,5 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="1.5.13/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.5.55/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>giveaway</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>giveaway-int</artifactId>
|
||||
|
||||
@@ -2,6 +2,7 @@ package dev.sheldan.abstracto.giveaway.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import dev.sheldan.abstracto.core.config.PostTargetEnum;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -11,6 +12,8 @@ import java.util.List;
|
||||
@Component
|
||||
public class GiveawayFeatureConfig implements FeatureConfig {
|
||||
|
||||
public static final String KEY_GIVEAWAYS_DURATION = "keyGiveawaysDuration";
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return GiveawayFeatureDefinition.GIVEAWAY;
|
||||
@@ -20,4 +23,14 @@ public class GiveawayFeatureConfig implements FeatureConfig {
|
||||
public List<PostTargetEnum> getRequiredPostTargets() {
|
||||
return Arrays.asList(GiveawayPostTarget.GIVEAWAYS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FeatureMode> getAvailableModes() {
|
||||
return Arrays.asList(GiveawayMode.KEY_GIVEAWAYS, GiveawayMode.AUTO_NOTIFY_GIVEAWAY_KEY_WINNERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRequiredSystemConfigKeys() {
|
||||
return Arrays.asList(KEY_GIVEAWAYS_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.sheldan.abstracto.giveaway.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum GiveawayMode implements FeatureMode {
|
||||
KEY_GIVEAWAYS("keyGiveaways"),
|
||||
AUTO_NOTIFY_GIVEAWAY_KEY_WINNERS("autoNotifyGiveawayKeyWinners");
|
||||
|
||||
private final String key;
|
||||
|
||||
GiveawayMode(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package dev.sheldan.abstracto.giveaway.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
|
||||
public class GiveawayKeyNotFoundException extends AbstractoTemplatableException {
|
||||
public GiveawayKeyNotFoundException() {
|
||||
super("Giveaway key not found.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "giveaway_key_not_found_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package dev.sheldan.abstracto.giveaway.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
|
||||
public class GiveawayNotPossibleException extends AbstractoTemplatableException {
|
||||
public GiveawayNotPossibleException() {
|
||||
super("Giveaway not possible.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "giveaway_not_possible_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package dev.sheldan.abstracto.giveaway.model;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
||||
|
||||
import java.time.Duration;
|
||||
@@ -12,8 +11,10 @@ import java.time.Duration;
|
||||
@Getter
|
||||
public class GiveawayCreationRequest {
|
||||
|
||||
private Member creator;
|
||||
private Member benefactor;
|
||||
private Long creatorId;
|
||||
private Long serverId;
|
||||
private Long benefactorId;
|
||||
private Long giveawayKeyId;
|
||||
private String title;
|
||||
private String description;
|
||||
private Duration duration;
|
||||
|
||||
@@ -65,6 +65,9 @@ public class Giveaway {
|
||||
@Column(name = "message_id", nullable = false)
|
||||
private Long messageId;
|
||||
|
||||
@OneToOne(mappedBy = "giveaway")
|
||||
private GiveawayKey giveawayKey;
|
||||
|
||||
@Column(name = "created", nullable = false, insertable = false, updatable = false)
|
||||
private Instant created;
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package dev.sheldan.abstracto.giveaway.model.database;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.embed.GiveawayKeyId;
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.EmbeddedId;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinColumns;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.MapsId;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Builder
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "giveaway_key")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
public class GiveawayKey {
|
||||
@Id
|
||||
@EmbeddedId
|
||||
private GiveawayKeyId id;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumns(
|
||||
{
|
||||
@JoinColumn(name = "giveaway_id", referencedColumnName = "id"),
|
||||
@JoinColumn(name = "giveaway_server_id", referencedColumnName = "server_id")
|
||||
})
|
||||
private Giveaway giveaway;
|
||||
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@MapsId("serverId")
|
||||
@JoinColumn(name = "server_id", referencedColumnName = "id", nullable = false)
|
||||
private AServer server;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "creator_user_id", nullable = false)
|
||||
private AUserInAServer creator;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "winner_user_id")
|
||||
private AUserInAServer winner;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "benefactor_user_id")
|
||||
private AUserInAServer benefactor;
|
||||
|
||||
@Column(name = "key", nullable = false)
|
||||
private String key;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "used")
|
||||
private Boolean used;
|
||||
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package dev.sheldan.abstracto.giveaway.model.database.embed;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Embeddable;
|
||||
import java.io.Serializable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Embeddable
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@EqualsAndHashCode
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class GiveawayKeyId implements Serializable {
|
||||
@Column(name = "id")
|
||||
private Long keyId;
|
||||
|
||||
@Column(name = "server_id")
|
||||
private Long serverId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.sheldan.abstracto.giveaway.model.template;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class GiveawayKeyDisplayModel {
|
||||
private String key;
|
||||
private String name;
|
||||
private Long id;
|
||||
private String description;
|
||||
private Boolean used;
|
||||
private MemberDisplay creator;
|
||||
private MemberDisplay benefactor;
|
||||
private MemberDisplay winner;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package dev.sheldan.abstracto.giveaway.model.template;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class GiveawayKeysDisplayModel {
|
||||
private List<GiveawayKeyDisplayModel> keys;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package dev.sheldan.abstracto.giveaway.model.template;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.Giveaway;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
@Setter
|
||||
public class GiveawayWinnerNotificationMessageModel {
|
||||
private String title;
|
||||
private String description;
|
||||
private String key;
|
||||
private Long giveawayId;
|
||||
private MemberDisplay creator;
|
||||
private MemberDisplay benefactor;
|
||||
|
||||
public static GiveawayWinnerNotificationMessageModel fromGiveaway(Giveaway giveaway, String key) {
|
||||
return GiveawayWinnerNotificationMessageModel
|
||||
.builder()
|
||||
.title(giveaway.getTitle())
|
||||
.description(giveaway.getDescription())
|
||||
.key(key)
|
||||
.benefactor(giveaway.getBenefactor() != null ? MemberDisplay.fromAUserInAServer(giveaway.getBenefactor()) : null)
|
||||
.creator(MemberDisplay.fromAUserInAServer(giveaway.getCreator()))
|
||||
.giveawayId(giveaway.getGiveawayId().getId())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface GiveawayService {
|
||||
CompletableFuture<Void> createGiveaway(GiveawayCreationRequest giveawayCreationRequest);
|
||||
CompletableFuture<Long> createGiveaway(GiveawayCreationRequest giveawayCreationRequest);
|
||||
CompletableFuture<Void> addGiveawayParticipant(Giveaway giveaway, Member member, MessageChannel messageChannel);
|
||||
CompletableFuture<Void> evaluateGiveaway(Long giveawayId, Long serverId);
|
||||
CompletableFuture<Void> cancelGiveaway(Long giveawayId, Long serverId);
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.abstracto.giveaway.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.giveaway.model.database.GiveawayKey;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
public interface GiveawayKeyManagementService {
|
||||
GiveawayKey createGiveawayKey(Member creator, Member benefactor, String key, String description, String name);
|
||||
void deleteById(Long id, Long serverId);
|
||||
Optional<GiveawayKey> getById(Long id, Long serverId);
|
||||
GiveawayKey saveGiveawayKey(GiveawayKey giveawayKey);
|
||||
List<GiveawayKey> getGiveawayKeys(Long serverId, Boolean ignoreUsedFlag);
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>giveaway</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>image-generation</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>image-generation-impl</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>image-generation</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>image-generation-int</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>image-generation</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>invite-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>invite-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation-int</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>link-embed</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>link-embed</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>logging</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>logging</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@ import dev.sheldan.abstracto.moderation.model.interaction.ModerationActionMutePa
|
||||
import dev.sheldan.abstracto.moderation.model.template.listener.ModerationActionMuteModalModel;
|
||||
import dev.sheldan.abstracto.moderation.model.template.listener.ModerationActionPayloadModel;
|
||||
import dev.sheldan.abstracto.moderation.service.ModerationActionServiceBean;
|
||||
import jakarta.transaction.Transactional;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>modmail</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.core.utils.SnowflakeUtils;
|
||||
import dev.sheldan.abstracto.moderation.service.BanService;
|
||||
import dev.sheldan.abstracto.modmail.config.ModMailFeatureConfig;
|
||||
import dev.sheldan.abstracto.modmail.config.ModMailFeatureDefinition;
|
||||
@@ -28,6 +29,7 @@ import dev.sheldan.abstracto.modmail.exception.ModMailThreadNotFoundException;
|
||||
import dev.sheldan.abstracto.modmail.model.ClosingContext;
|
||||
import dev.sheldan.abstracto.modmail.model.dto.ServiceChoicesPayload;
|
||||
import dev.sheldan.abstracto.modmail.model.database.*;
|
||||
import dev.sheldan.abstracto.modmail.model.listener.ModmailThreadCreatedSendMessageModel;
|
||||
import dev.sheldan.abstracto.modmail.model.template.*;
|
||||
import dev.sheldan.abstracto.modmail.service.management.ModMailMessageManagementService;
|
||||
import dev.sheldan.abstracto.modmail.service.management.ModMailRoleManagementService;
|
||||
@@ -46,6 +48,7 @@ import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
|
||||
import net.dv8tion.jda.api.interactions.InteractionHook;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -56,6 +59,7 @@ import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.transaction.event.TransactionalEventListener;
|
||||
|
||||
import static dev.sheldan.abstracto.modmail.config.ModMailFeatureConfig.MOD_MAIL_CLOSING_TEXT_SYSTEM_CONFIG_KEY;
|
||||
|
||||
@@ -159,6 +163,9 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
public static final String MODMAIL_THREAD_METRIC = "modmail.threads";
|
||||
public static final String MODMAIL_MESSAGE_METRIC = "modmail.messges";
|
||||
public static final String ACTION = "action";
|
||||
@@ -189,8 +196,8 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
|
||||
public static final String MODMAIL_INITIAL_ORIGIN = "modmailInitial";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<MessageChannel> createModMailThreadForUser(User user, Guild guild, Message initialMessage, boolean userInitiated, List<UndoActionInstance> undoActions, boolean appeal) {
|
||||
public CompletableFuture<MessageChannel> createModMailThreadForUser(User user, Guild guild, Message initialMessage, boolean userInitiated, List<UndoActionInstance> undoActions,
|
||||
boolean appeal, ModmailThreadCreatedSendMessageModel createdSendMessageModel) {
|
||||
Long serverId = guild.getIdLong();
|
||||
AServer server = serverManagementService.loadServer(serverId);
|
||||
metricService.incrementCounter(MODMAIL_THREAD_CREATED_COUNTER);
|
||||
@@ -220,7 +227,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
.thenCompose(unused -> channelService.createThreadWithStarterMessage(textChannel, channelName, notificationMessage.get(0).join().getIdLong()))
|
||||
.thenCompose(threadChannel -> {
|
||||
undoActions.add(UndoActionInstance.getChannelDeleteAction(serverId, threadChannel.getIdLong()));
|
||||
return self.performModMailThreadSetup(user, initialMessage, threadChannel, userInitiated, undoActions, appeal)
|
||||
return self.performModMailThreadSetup(user, initialMessage, threadChannel, userInitiated, undoActions, appeal, createdSendMessageModel)
|
||||
.thenCompose(unused -> CompletableFuture.completedFuture(threadChannel));
|
||||
});
|
||||
} else {
|
||||
@@ -229,12 +236,18 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
CompletableFuture<TextChannel> textChannelFuture = channelService.createTextChannel(channelName, server, categoryId);
|
||||
return textChannelFuture.thenCompose(channel -> {
|
||||
undoActions.add(UndoActionInstance.getChannelDeleteAction(serverId, channel.getIdLong()));
|
||||
return self.performModMailThreadSetup(user, initialMessage, channel, userInitiated, undoActions, appeal)
|
||||
return self.performModMailThreadSetup(user, initialMessage, channel, userInitiated, undoActions, appeal, createdSendMessageModel)
|
||||
.thenCompose(unused -> CompletableFuture.completedFuture(channel));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<MessageChannel> createModMailThreadForUser(User user, Guild guild, Message initialMessage, boolean userInitiated,
|
||||
List<UndoActionInstance> undoActions, boolean appeal) {
|
||||
return createModMailThreadForUser(user, guild, initialMessage, userInitiated, undoActions, appeal, null);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CompletableFuture<Void> sendContactNotification(User user, MessageChannel messageChannel, MessageChannel feedBackChannel) {
|
||||
@@ -265,10 +278,12 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
* @param userInitiated Whether the thread was initiated by a member
|
||||
* @param undoActions The list of actions to undo, in case an exception occurs
|
||||
* @param appeal Whether the modmail thread is for the purpose of an appeal
|
||||
* @param createdSendMessageModel The information which message should be sent after the modmail thread is completely created
|
||||
* @return A {@link CompletableFuture future} which completes when the setup is done
|
||||
*/
|
||||
@Transactional
|
||||
public CompletableFuture<Void> performModMailThreadSetup(User user, Message initialMessage, GuildMessageChannel channel, boolean userInitiated, List<UndoActionInstance> undoActions, boolean appeal) {
|
||||
public CompletableFuture<Void> performModMailThreadSetup(User user, Message initialMessage, GuildMessageChannel channel, boolean userInitiated, List<UndoActionInstance> undoActions,
|
||||
boolean appeal, ModmailThreadCreatedSendMessageModel createdSendMessageModel) {
|
||||
log.info("Performing modmail thread setup for channel {} for user {} in server {}. It was initiated by a user: {}.", channel.getIdLong(), user.getId(), channel.getGuild().getId(), userInitiated);
|
||||
CompletableFuture<Void> headerFuture = sendModMailHeader(channel, user);
|
||||
CompletableFuture<Message> userReplyMessage;
|
||||
@@ -287,18 +302,22 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
}
|
||||
return CompletableFuture.allOf(headerFuture, notificationFuture, userReplyMessage).thenAccept(aVoid -> {
|
||||
undoActions.clear();
|
||||
self.setupModMailThreadInDB(initialMessage, channel, user, userReplyMessage.join(), appeal);
|
||||
self.setupModMailThreadInDB(initialMessage, channel, user, userReplyMessage.join(), appeal, createdSendMessageModel);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void setupModMailThreadInDB(Message initialMessage, GuildMessageChannel channel, User user, Message sendMessage, boolean appeal) {
|
||||
public void setupModMailThreadInDB(Message initialMessage, GuildMessageChannel channel, User user, Message sendMessage, boolean appeal,
|
||||
ModmailThreadCreatedSendMessageModel createdSendMessageModel) {
|
||||
log.info("Persisting info about modmail thread {} in database.", channel.getIdLong());
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(channel.getGuild().getIdLong(), user.getIdLong());
|
||||
ModMailThread thread = createThreadObject(channel, aUserInAServer, appeal);
|
||||
if(initialMessage != null) {
|
||||
log.debug("Adding initial message {} to modmail thread in channel {}.", initialMessage.getId(), channel.getId());
|
||||
modMailMessageManagementService.addMessageToThread(thread, null, sendMessage, initialMessage, aUserInAServer, false, false);
|
||||
modMailMessageManagementService.addMessageToThread(thread, null, sendMessage, initialMessage.getIdLong(), aUserInAServer, false, false);
|
||||
}
|
||||
if(createdSendMessageModel != null) {
|
||||
eventPublisher.publishEvent(createdSendMessageModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,6 +546,59 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> sendMessageToUser(AUserInAServer aUserInAServer, MessageToSend messageToSendToUser, User user) {
|
||||
AServer aServer = aUserInAServer.getServerReference();
|
||||
Long serverId = aServer.getId();
|
||||
Long userId = user.getIdLong();
|
||||
Guild guild = guildService.getGuildById(serverId);
|
||||
if(modMailThreadManagementService.hasOpenModMailThreadForUser(aUserInAServer)) {
|
||||
return sendMessageToExistingModmailThread(aUserInAServer, messageToSendToUser, user);
|
||||
} else {
|
||||
List<UndoActionInstance> undoActionInstances = new ArrayList<>();
|
||||
ModmailThreadCreatedSendMessageModel createdSendMessageModel = ModmailThreadCreatedSendMessageModel
|
||||
.builder()
|
||||
.messageToSend(messageToSendToUser)
|
||||
.userId(userId)
|
||||
.serverId(serverId)
|
||||
.build();
|
||||
return createModMailThreadForUser(user, guild, null, false, undoActionInstances, false, createdSendMessageModel).thenAccept(messageChannel -> {
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to setup modmail thread correctly", throwable);
|
||||
undoActionService.performActions(undoActionInstances);
|
||||
throw new AbstractoRunTimeException(throwable);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> sendMessageToExistingModmailThread(AUserInAServer aUserInAServer, MessageToSend messageToSendToUser, User user) {
|
||||
ModMailThread modmailThread = modMailThreadManagementService.getOpenModMailThreadForUser(aUserInAServer);
|
||||
CompletableFuture<Message> future = messageService.sendMessageToSendToUser(user, messageToSendToUser);
|
||||
CompletableFuture<Message> sameThreadMessageFuture = channelService.sendMessageEmbedToSendToAChannel(messageToSendToUser, modmailThread.getChannel()).get(0);
|
||||
Long modmailThreadId = modmailThread.getId();
|
||||
Guild guild = guildService.getGuildById(aUserInAServer.getServerReference().getId());
|
||||
return CompletableFuture.allOf(future, sameThreadMessageFuture).thenAccept(avoid ->
|
||||
self.saveSendMessagesAndUpdateState(modmailThreadId, false, future.join(), guild.getSelfMember(), SnowflakeUtils.createSnowFlake(), sameThreadMessageFuture.join())
|
||||
);
|
||||
}
|
||||
|
||||
@TransactionalEventListener
|
||||
public void sendMessageAfterModmailThreadCreated(ModmailThreadCreatedSendMessageModel model) {
|
||||
log.info("Sending message to {} in server {} after modmail thread was created.", model.getUserId(), model.getServerId());
|
||||
userService.retrieveUserForId(model.getUserId())
|
||||
.thenCompose(user -> self.loadUserAndSendtoModmail(model, user))
|
||||
.exceptionally(throwable -> {
|
||||
log.warn("Failed to load user to send modmail thread to.");
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> loadUserAndSendtoModmail(ModmailThreadCreatedSendMessageModel model, User user) {
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.onlyLoadUser(model.getServerId(), model.getUserId());
|
||||
return sendMessageToExistingModmailThread(aUserInAServer, model.getMessageToSend(), user);
|
||||
}
|
||||
|
||||
/**
|
||||
* This message takes a received {@link Message} from a user, renders it to a new message to send and sends it to
|
||||
* the appropriate {@link ModMailThread} channel, the returned promise only returns if the message was dealt with on the user
|
||||
@@ -622,7 +694,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
if(modMailThreadOpt.isPresent()) {
|
||||
ModMailThread modMailThread = modMailThreadOpt.get();
|
||||
log.debug("Adding created message {} based on messeage {} sent from user to modmail thread {} and setting status to {}.", messageInModMailThread.getId(), messageFromUser.getId(), modMailThread.getId(), ModMailThreadState.USER_REPLIED);
|
||||
modMailMessageManagementService.addMessageToThread(modMailThread, null, messageInModMailThread, messageFromUser, modMailThread.getUser(), false, false);
|
||||
modMailMessageManagementService.addMessageToThread(modMailThread, null, messageInModMailThread, messageFromUser.getIdLong(), modMailThread.getUser(), false, false);
|
||||
// update the state of the thread
|
||||
modMailThreadManagementService.setModMailThreadState(modMailThread, ModMailThreadState.USER_REPLIED);
|
||||
} else {
|
||||
@@ -678,7 +750,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
sameThreadMessageFuture = CompletableFuture.completedFuture(null);
|
||||
}
|
||||
return CompletableFuture.allOf(future, sameThreadMessageFuture).thenAccept(avoid ->
|
||||
self.saveSendMessagesAndUpdateState(modmailThreadId, anonymous, future.join(), replyCommandMessage, sameThreadMessageFuture.join())
|
||||
self.saveSendMessagesAndUpdateState(modmailThreadId, anonymous, future.join(), replyCommandMessage.getMember(), replyCommandMessage.getIdLong(), sameThreadMessageFuture.join())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1009,17 +1081,18 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
* @param anonymous Whether or not the messages were send anonymous
|
||||
* @param createdMessageInDM The {@link Message message} which was sent to the private channel with the {@link User user}
|
||||
* @param modMailThreadMessage The {@link Message message} which was sent in the channel representing the {@link ModMailThread thread}. Might be null.
|
||||
* @param replyCommandMessage The {@link Message message} which contained the command used to reply to the user
|
||||
* @param author The {@link Member} which caused the message to be sent
|
||||
* @param messageId The ID of the message that was sent
|
||||
* @throws ModMailThreadNotFoundException in case the {@link ModMailThread} is not found by the ID
|
||||
*/
|
||||
@Transactional
|
||||
public void saveSendMessagesAndUpdateState(Long modMailThreadId, Boolean anonymous, Message createdMessageInDM, Message replyCommandMessage, Message modMailThreadMessage) {
|
||||
public void saveSendMessagesAndUpdateState(Long modMailThreadId, Boolean anonymous, Message createdMessageInDM, Member author, Long messageId, Message modMailThreadMessage) {
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getByIdOptional(modMailThreadId);
|
||||
AUserInAServer moderator = userInServerManagementService.loadOrCreateUser(replyCommandMessage.getMember());
|
||||
AUserInAServer moderator = userInServerManagementService.loadOrCreateUser(author);
|
||||
if(modMailThreadOpt.isPresent()) {
|
||||
ModMailThread modMailThread = modMailThreadOpt.get();
|
||||
log.debug("Adding (anonymous: {}) message {} of moderator to modmail thread {} and setting state to {}.", anonymous, createdMessageInDM.getId(), modMailThreadId, ModMailThreadState.MOD_REPLIED);
|
||||
modMailMessageManagementService.addMessageToThread(modMailThread, createdMessageInDM, modMailThreadMessage, replyCommandMessage, moderator, anonymous, true);
|
||||
modMailMessageManagementService.addMessageToThread(modMailThread, createdMessageInDM, modMailThreadMessage, messageId, moderator, anonymous, true);
|
||||
modMailThreadManagementService.setModMailThreadState(modMailThread, ModMailThreadState.MOD_REPLIED);
|
||||
} else {
|
||||
throw new ModMailThreadNotFoundException(modMailThreadId);
|
||||
|
||||
@@ -20,13 +20,13 @@ public class ModMailMessageManagementServiceBean implements ModMailMessageManage
|
||||
private ModMailMessageRepository modMailMessageRepository;
|
||||
|
||||
@Override
|
||||
public ModMailMessage addMessageToThread(ModMailThread modMailThread, Message createdMessageInDM, Message createdMessageInChannel, Message userPostedMessage, AUserInAServer author, Boolean anonymous, Boolean dmChannel) {
|
||||
public ModMailMessage addMessageToThread(ModMailThread modMailThread, Message createdMessageInDM, Message createdMessageInChannel, Long messageId, AUserInAServer author, Boolean anonymous, Boolean dmChannel) {
|
||||
Long dmId = createdMessageInDM != null ? createdMessageInDM.getIdLong() : null;
|
||||
Long channelMessageId = createdMessageInChannel != null ? createdMessageInChannel.getIdLong() : null;
|
||||
ModMailMessage modMailMessage = ModMailMessage
|
||||
.builder()
|
||||
.author(author)
|
||||
.messageId(userPostedMessage.getIdLong())
|
||||
.messageId(messageId)
|
||||
.createdMessageInDM(dmId)
|
||||
.server(modMailThread.getServer())
|
||||
.createdMessageInChannel(channelMessageId)
|
||||
@@ -35,7 +35,7 @@ public class ModMailMessageManagementServiceBean implements ModMailMessageManage
|
||||
.anonymous(anonymous)
|
||||
.build();
|
||||
log.info("Storing created message in DM {} with created message in channel {} caused by message {} to modmail thread {} of user {} in server {}.",
|
||||
dmId, channelMessageId, userPostedMessage.getId(), modMailThread.getId(), author.getUserReference().getId(), author.getServerReference().getId());
|
||||
dmId, channelMessageId, messageId, modMailThread.getId(), author.getUserReference().getId(), author.getServerReference().getId());
|
||||
|
||||
return modMailMessageRepository.save(modMailMessage);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>modmail</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.abstracto.modmail.model.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class ModmailThreadCreatedSendMessageModel {
|
||||
private MessageToSend messageToSend;
|
||||
private Long serverId;
|
||||
private Long userId;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.models.UndoActionInstance;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.modmail.model.ClosingContext;
|
||||
import dev.sheldan.abstracto.modmail.model.database.ModMailThread;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
@@ -62,6 +63,7 @@ public interface ModMailThreadService {
|
||||
* @return A {@link CompletableFuture future} which completes when the message has been relayed to the channel
|
||||
*/
|
||||
CompletableFuture<Message> relayMessageToModMailThread(ModMailThread modMailThread, Message messageFromUser, List<UndoActionInstance> undoActions);
|
||||
CompletableFuture<Void> sendMessageToUser(AUserInAServer aUserInAServer, MessageToSend messageToSend, User user);
|
||||
|
||||
/**
|
||||
* Forwards a message send by a moderator to the direct message channel opened with the user. If the message is
|
||||
|
||||
@@ -17,13 +17,13 @@ public interface ModMailMessageManagementService {
|
||||
* @param modMailThread The {@link ModMailThread} the message should be attached to
|
||||
* @param createdMessageInDM The {@link Message} which should be attached to the {@link ModMailThread} and was posted to the DM channel (might be null)
|
||||
* @param createdMessageInChannel The {@link Message} which should be attached to the {@link ModMailThread} and was posted to the modmail thread (might be null)
|
||||
* @param userPostedMessage The {@link Message} which caused this message to be created, the command or the message by the user
|
||||
* @param messageId The ID of the {@link Message} which caused this message to be created, the command or the message by the user
|
||||
* @param author The {@link AUserInAServer} who authored the {@link Message} originally
|
||||
* @param anonymous Whether or not the message was sent anonymous (only possible by staff members)
|
||||
* @param dmChannel Whether or not the message originated from the user, and therefore in an direct message channel
|
||||
* @return The created {@link ModMailMessage message} instance
|
||||
*/
|
||||
ModMailMessage addMessageToThread(ModMailThread modMailThread, Message createdMessageInDM, Message createdMessageInChannel, Message userPostedMessage, AUserInAServer author, Boolean anonymous, Boolean dmChannel);
|
||||
ModMailMessage addMessageToThread(ModMailThread modMailThread, Message createdMessageInDM, Message createdMessageInChannel, Long messageId, AUserInAServer author, Boolean anonymous, Boolean dmChannel);
|
||||
|
||||
/**
|
||||
* Retrieves all messages which were sent in a {@link ModMailThread}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto</groupId>
|
||||
<artifactId>abstracto-application</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>profanity-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>profanity-filter</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>remind</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>remind</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>repost-detection</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>repost-detection</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>starboard</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>starboard</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>statistic</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>statistic</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>sticky-roles</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>sticky-roles-impl</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>sticky-roles</artifactId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>sticky-roles-int</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>suggestion</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>suggestion</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>twitch</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.53-SNAPSHOT</version>
|
||||
<version>1.5.56</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user