[OPB-19] adding referral link functionality

changing name for setups feature
aligning starboard custom module name
This commit is contained in:
Sheldan
2021-05-12 00:14:18 +02:00
parent 67ae9702fd
commit e236522328
75 changed files with 2302 additions and 98 deletions

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>oneplus-bot-modules</artifactId>
<groupId>dev.sheldan.oneplus.bot.application.modules</groupId>
<version>1.3.11-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>setup</artifactId>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/liquibase.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,18 @@
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>liquibase</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<outputDirectory>.</outputDirectory>
<directory>${project.basedir}/src/main/resources/migrations</directory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
</fileSets>
</assembly>

View File

@@ -0,0 +1,15 @@
package dev.sheldan.oneplus.bot.modules.setup.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@Configuration
public class SetupBeanConfig {
@Bean(value = "setupDelayedExecutor")
public ScheduledExecutorService getDelayedExecutor() {
return Executors.newSingleThreadScheduledExecutor();
}
}

View File

@@ -0,0 +1,30 @@
package dev.sheldan.oneplus.bot.modules.setup.config;
import dev.sheldan.abstracto.core.config.FeatureConfig;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.config.PostTargetEnum;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import static dev.sheldan.oneplus.bot.modules.setup.listener.SetupListener.SETUP_UPVOTE_EMOTE_KEY;
@Component
public class SetupFeatureConfig implements FeatureConfig {
@Override
public FeatureDefinition getFeature() {
return SetupFeatureDefinition.SETUP;
}
@Override
public List<PostTargetEnum> getRequiredPostTargets() {
return Arrays.asList(SetupPostTarget.SETUP);
}
@Override
public List<String> getRequiredEmotes() {
return Arrays.asList(SETUP_UPVOTE_EMOTE_KEY);
}
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.oneplus.bot.modules.setup.config;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import lombok.Getter;
@Getter
public enum SetupFeatureDefinition implements FeatureDefinition {
SETUP("setup");
private String key;
SetupFeatureDefinition(String key) {
this.key = key;
}
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.oneplus.bot.modules.setup.config;
import dev.sheldan.abstracto.core.config.PostTargetEnum;
import lombok.Getter;
@Getter
public enum SetupPostTarget implements PostTargetEnum {
SETUP("setup");
private String key;
SetupPostTarget(String key) {
this.key = key;
}
}

View File

@@ -0,0 +1,10 @@
package dev.sheldan.oneplus.bot.modules.setup.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:setup.properties")
public class SetupProperties {
}

View File

@@ -0,0 +1,99 @@
package dev.sheldan.oneplus.bot.modules.setup.listener;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageReceivedListener;
import dev.sheldan.abstracto.core.models.database.PostTarget;
import dev.sheldan.abstracto.core.models.listener.MessageReceivedModel;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.core.service.ReactionService;
import dev.sheldan.abstracto.core.service.management.PostTargetManagement;
import dev.sheldan.oneplus.bot.modules.setup.config.SetupFeatureDefinition;
import dev.sheldan.oneplus.bot.modules.setup.config.SetupPostTarget;
import dev.sheldan.oneplus.bot.modules.setup.service.SetupServiceBean;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Optional;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
public class SetupListener implements AsyncMessageReceivedListener {
@Autowired
private PostTargetManagement postTargetManagement;
@Autowired
private SetupServiceBean setupServiceBean;
@Qualifier("setupDelayedExecutor")
@Autowired
private ScheduledExecutorService scheduledExecutorService;
@Value("${oneplus.bot.setup.deletionDelaySeconds}")
private Long deletionDelay;
@Autowired
private MessageService messageService;
@Autowired
private ReactionService reactionService;
public static final String SETUP_UPVOTE_EMOTE_KEY = "setupUpvote";
@Override
public DefaultListenerResult execute(MessageReceivedModel model) {
Long serverId = model.getServerId();
Optional<PostTarget> setupPostTargetOptional = postTargetManagement.getPostTargetOptional(SetupPostTarget.SETUP, serverId);
if(setupPostTargetOptional.isPresent()) {
PostTarget setupTarget = setupPostTargetOptional.get();
Message originalMessage = model.getMessage();
if(originalMessage.getChannel().getIdLong() == setupTarget.getChannelReference().getId()) {
if(!originalMessage.isFromGuild() || originalMessage.isWebhookMessage() || originalMessage.getType().isSystem()) {
messageService.deleteMessage(originalMessage);
return DefaultListenerResult.IGNORED;
}
boolean currentlyInvalid = setupServiceBean.currentlyInvalid(originalMessage);
if(currentlyInvalid) {
if(setupServiceBean.mightContainEmbed(originalMessage)) {
log.info("Setup message did not contain embeds not attachments, but a link - waiting for embeds on message {}" +
" in channel {} in guild {} by user {}.", originalMessage.getIdLong(), originalMessage.getChannel().getIdLong(),
originalMessage.getGuild().getIdLong(), originalMessage.getAuthor().getIdLong());
scheduledExecutorService.schedule(() -> {
messageService.loadMessage(originalMessage).thenAccept(loadedMessage -> {
if(setupServiceBean.currentlyInvalid(loadedMessage)) {
log.info("Message did not contain attachments nor embeds after a delay - deleting setup message {}.", loadedMessage.getIdLong());
messageService.deleteMessage(loadedMessage);
} else {
log.info("Message contained embeds/attachments after a delay - message was accepted {}.", loadedMessage.getIdLong());
reactionService.addReactionToMessage(SETUP_UPVOTE_EMOTE_KEY, serverId, loadedMessage);
}
});
}, deletionDelay, TimeUnit.SECONDS);
} else {
log.info("Did not find any attachments nor embeds and no link to lead to any embeds - deleting setup message {} in channel {} in server {}" +
"by user {} for setup.", originalMessage.getIdLong(), originalMessage.getChannel().getIdLong(), originalMessage.getGuild().getIdLong(),
originalMessage.getAuthor().getIdLong());
messageService.deleteMessage(originalMessage);
}
} else {
log.info("Accepting setup message {} in channel {} in guild {} from user {}.", originalMessage.getIdLong(),
originalMessage.getChannel().getIdLong(), originalMessage.getGuild().getIdLong(), originalMessage.getAuthor().getIdLong());
reactionService.addReactionToMessage(SETUP_UPVOTE_EMOTE_KEY, serverId, originalMessage);
}
}
}
return DefaultListenerResult.IGNORED;
}
@Override
public FeatureDefinition getFeature() {
return SetupFeatureDefinition.SETUP;
}
}

View File

@@ -0,0 +1,35 @@
package dev.sheldan.oneplus.bot.modules.setup.service;
import net.dv8tion.jda.api.entities.EmbedType;
import net.dv8tion.jda.api.entities.Message;
import org.springframework.stereotype.Component;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Component
public class SetupServiceBean {
private static final Pattern URL_REGEX = Pattern.compile("((https?|ftp)://|(www|ftp)\\.)?[a-z0-9-]+(\\.[a-z0-9-]+)+([/?].*)?");
public boolean mightContainEmbed(Message message) {
Matcher urlMatcher = URL_REGEX.matcher(message.getContentRaw());
return urlMatcher.find();
}
public boolean currentlyValid(Message message) {
return !message.getAttachments().isEmpty() ||
(
!message.getEmbeds().isEmpty() &&
message
.getEmbeds()
.stream()
.anyMatch(messageEmbed -> messageEmbed.getType().equals(EmbedType.IMAGE))
);
}
public boolean currentlyInvalid(Message message) {
return !currentlyValid(message);
}
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<include file="setup-seedData/data.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,11 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<include file="feature.xml" relativeToChangelogFile="true"/>
<include file="default_emote.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,15 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<changeSet author="Sheldan" id="setup_default_emote-insert">
<insert tableName="default_emote">
<column name="emote_key" value="setupUpvote"/>
<column name="name" value="👍"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,14 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<changeSet author="Sheldan" id="setup_feature-insertion">
<insert tableName="feature">
<column name="key" value="setup"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<include file="1.3.11-setup/collection.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,6 @@
abstracto.postTargets.setup.name=setup
abstracto.featureFlags.setup.featureName=setup
abstracto.featureFlags.setup.enabled=false
oneplus.bot.setup.deletionDelaySeconds=3