[OPB-12] adding news/newsupdate command and introducing mechanisms for cleanup thereof

changing templates to have the metaconfig
moving starboard custom templates
This commit is contained in:
Sheldan
2021-04-24 01:38:59 +02:00
parent d860ad6291
commit bf55064984
64 changed files with 2477 additions and 10 deletions

View File

@@ -101,6 +101,12 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>dev.sheldan.oneplus.bot.application.modules</groupId>
<artifactId>news</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,41 @@
<?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>
<groupId>dev.sheldan.oneplus.bot.application.modules</groupId>
<artifactId>oneplus-bot-modules</artifactId>
<version>1.3.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>news</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<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,54 @@
package dev.sheldan.oneplus.bot.modules.news.commands;
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.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.oneplus.bot.modules.news.config.NewsFeatureDefinition;
import dev.sheldan.oneplus.bot.modules.news.config.NewsModuleDefinition;
import dev.sheldan.oneplus.bot.modules.news.service.NewsServiceBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class News extends AbstractConditionableCommand {
@Autowired
private NewsServiceBean newsServiceBean;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
String text = (String) commandContext.getParameters().getParameters().get(0);
return newsServiceBean.sendNewsPost(text, commandContext.getMessage())
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
Parameter newsText = Parameter.builder().name("text").type(String.class).remainder(true).templated(true).build();
List<Parameter> parameters = Arrays.asList(newsText);
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
return CommandConfiguration.builder()
.name("news")
.module(NewsModuleDefinition.NEWS)
.parameters(parameters)
.supportsEmbedException(true)
.async(true)
.help(helpInfo)
.templated(true)
.causesReaction(true)
.build();
}
@Override
public FeatureDefinition getFeature() {
return NewsFeatureDefinition.NEWS;
}
}

View File

@@ -0,0 +1,57 @@
package dev.sheldan.oneplus.bot.modules.news.commands;
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.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.oneplus.bot.modules.news.config.NewsFeatureDefinition;
import dev.sheldan.oneplus.bot.modules.news.config.NewsModuleDefinition;
import dev.sheldan.oneplus.bot.modules.news.service.NewsServiceBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class UpdateNews extends AbstractConditionableCommand {
@Autowired
private NewsServiceBean newsServiceBean;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Long messageId = (Long) parameters.get(0);
String postText = (String) parameters.get(1);
return newsServiceBean.updateNewsPostViaId(messageId, postText, commandContext.getMessage())
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
Parameter newsPostId = Parameter.builder().name("newsPostId").type(Long.class).templated(true).build();
Parameter newsText = Parameter.builder().name("text").type(String.class).remainder(true).templated(true).build();
List<Parameter> parameters = Arrays.asList(newsPostId, newsText);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("updateNews")
.module(NewsModuleDefinition.NEWS)
.parameters(parameters)
.supportsEmbedException(true)
.async(true)
.help(helpInfo)
.templated(true)
.causesReaction(true)
.build();
}
@Override
public FeatureDefinition getFeature() {
return NewsFeatureDefinition.NEWS;
}
}

View File

@@ -0,0 +1,23 @@
package dev.sheldan.oneplus.bot.modules.news.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;
@Component
public class NewsFeature implements FeatureConfig {
@Override
public FeatureDefinition getFeature() {
return NewsFeatureDefinition.NEWS;
}
@Override
public List<PostTargetEnum> getRequiredPostTargets() {
return Arrays.asList(NewsPostTarget.NEWS_TARGET);
}
}

View File

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

View File

@@ -0,0 +1,21 @@
package dev.sheldan.oneplus.bot.modules.news.config;
import dev.sheldan.abstracto.core.command.config.ModuleDefinition;
import dev.sheldan.abstracto.core.command.config.ModuleInfo;
import org.springframework.stereotype.Component;
@Component
public class NewsModuleDefinition implements ModuleDefinition {
public static final String NEWS = "news";
@Override
public ModuleInfo getInfo() {
return ModuleInfo.builder().name(NEWS).templated(true).build();
}
@Override
public String getParentModule() {
return "default";
}
}

View File

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

View File

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

View File

@@ -0,0 +1,16 @@
package dev.sheldan.oneplus.bot.modules.news.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.templating.Templatable;
public class NewsPostLockedException extends AbstractoRunTimeException implements Templatable {
@Override
public String getTemplateName() {
return "news_post_locked_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -0,0 +1,16 @@
package dev.sheldan.oneplus.bot.modules.news.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.templating.Templatable;
public class NewsPostNotFoundException extends AbstractoRunTimeException implements Templatable {
@Override
public String getTemplateName() {
return "news_post_not_found_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -0,0 +1,31 @@
package dev.sheldan.oneplus.bot.modules.news.job;
import dev.sheldan.oneplus.bot.modules.news.service.NewsServiceBean;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
@Slf4j
@DisallowConcurrentExecution
@Component
@PersistJobDataAfterExecution
public class NewsPostCleanupJob extends QuartzJobBean {
@Autowired
private NewsServiceBean newsServiceBean;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
try {
log.info("Executing news post cleanup job.");
newsServiceBean.cleanUpNewsPosts();
} catch (Exception exception) {
log.error("Failed to execute news post cleanup job.", exception);
}
}
}

View File

@@ -0,0 +1,31 @@
package dev.sheldan.oneplus.bot.modules.news.job;
import dev.sheldan.oneplus.bot.modules.news.service.NewsServiceBean;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
@Slf4j
@DisallowConcurrentExecution
@Component
@PersistJobDataAfterExecution
public class NewsPostLockingJob extends QuartzJobBean {
@Autowired
private NewsServiceBean newsServiceBean;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
try {
log.info("Executing news post lock job.");
newsServiceBean.lockNewsPosts();
} catch (Exception exception) {
log.error("Failed to execute news post lock job.", exception);
}
}
}

View File

@@ -0,0 +1,46 @@
package dev.sheldan.oneplus.bot.modules.news.listener;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageTextUpdatedListener;
import dev.sheldan.abstracto.core.models.listener.MessageTextUpdatedModel;
import dev.sheldan.oneplus.bot.modules.news.config.NewsFeatureDefinition;
import dev.sheldan.oneplus.bot.modules.news.model.database.NewsPost;
import dev.sheldan.oneplus.bot.modules.news.service.NewsServiceBean;
import dev.sheldan.oneplus.bot.modules.news.service.management.NewsPostManagementServiceBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
@Slf4j
public class NewsMessageSourceMessageUpdatedListener implements AsyncMessageTextUpdatedListener {
@Autowired
private NewsPostManagementServiceBean newsPostManagementServiceBean;
@Autowired
private NewsServiceBean newsServiceBean;
@Override
public DefaultListenerResult execute(MessageTextUpdatedModel model) {
Optional<NewsPost> existingPostOptional = newsPostManagementServiceBean.getNewsPostForSourceMessage(model.getAfter().getIdLong());
if(existingPostOptional.isPresent()) {
NewsPost newsPost = existingPostOptional.get();
if(!newsPost.isLocked()) {
newsServiceBean.updateNewsPost(newsPost, model.getAfter());
return DefaultListenerResult.PROCESSED;
} else {
log.info("Not updating news post {}, because it is locked.", newsPost.getSourceMessageId());
}
}
return DefaultListenerResult.IGNORED;
}
@Override
public FeatureDefinition getFeature() {
return NewsFeatureDefinition.NEWS;
}
}

View File

@@ -0,0 +1,18 @@
package dev.sheldan.oneplus.bot.modules.news.model;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.Role;
@Getter
@Setter
@Builder
public class NewsMessageModel {
private String messageText;
private Message message;
private Member author;
private Role newsRole;
}

View File

@@ -0,0 +1,51 @@
package dev.sheldan.oneplus.bot.modules.news.model.database;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import lombok.*;
import javax.persistence.*;
import java.time.Instant;
@Builder
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "news_post")
@Getter
@Setter
@EqualsAndHashCode
public class NewsPost {
@Id
@Column(name = "source_message_id")
private Long sourceMessageId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "server_id", nullable = false)
private AServer server;
@Column(name = "news_message_id")
private Long newsMessageId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "author_user_in_server_id", nullable = false)
private AUserInAServer author;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "source_channel_id", nullable = false)
private AChannel sourceChannel;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "news_channel_id", nullable = false)
private AChannel newsChannel;
@Column(name = "locked")
private boolean locked;
@Column(name = "created")
private Instant created;
@Column(name = "updated")
private Instant updated;
}

View File

@@ -0,0 +1,17 @@
package dev.sheldan.oneplus.bot.modules.news.repository;
import dev.sheldan.oneplus.bot.modules.news.model.database.NewsPost;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
@Repository
public interface NewsPostRepository extends JpaRepository<NewsPost, Long> {
List<NewsPost> findByCreatedLessThanAndLockedFalse(Instant date);
List<NewsPost> findByUpdatedLessThanAndLockedTrue(Instant date);
Optional<NewsPost> findByNewsMessageId(Long newsMessageId);
}

View File

@@ -0,0 +1,127 @@
package dev.sheldan.oneplus.bot.modules.news.service;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.oneplus.bot.modules.news.config.NewsPostTarget;
import dev.sheldan.oneplus.bot.modules.news.exception.NewsPostLockedException;
import dev.sheldan.oneplus.bot.modules.news.model.NewsMessageModel;
import dev.sheldan.oneplus.bot.modules.news.model.database.NewsPost;
import dev.sheldan.oneplus.bot.modules.news.service.management.NewsPostManagementServiceBean;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
public class NewsServiceBean {
@Autowired
private PostTargetService postTargetService;
@Autowired
private TemplateService templateService;
@Autowired
private NewsPostManagementServiceBean newsPostManagementServiceBean;
@Autowired
private ChannelService channelService;
@Autowired
private NewsServiceBean self;
private static final String MESSAGE_TEMPLATE_KEY = "news_post";
@Value("${abstracto.feature.news.postLockSeconds}")
private Long postLockSeconds;
@Value("${abstracto.feature.news.removalDays}")
private Long removalDays;
@Transactional
public void lockNewsPosts() {
Instant oldestDate = Instant.now().minus(postLockSeconds, ChronoUnit.SECONDS).truncatedTo(ChronoUnit.DAYS);
log.info("Locking news posts older than {}.", oldestDate);
List<NewsPost> oldPosts = newsPostManagementServiceBean.findNewsPostsOlderNotLocked(oldestDate);
log.info("Locking {} news posts.", oldPosts.size());
oldPosts.forEach(newsPost -> newsPost.setLocked(true));
}
@Transactional
public void cleanUpNewsPosts() {
Instant oldestDate = Instant.now().minus(removalDays, ChronoUnit.DAYS).truncatedTo(ChronoUnit.DAYS);
log.info("Deleting news posts older than {}.", oldestDate);
List<NewsPost> oldPosts = newsPostManagementServiceBean.findNewsPostsUpdatedOlderThanAndLocked(oldestDate);
newsPostManagementServiceBean.deleteNewsPosts(oldPosts);
}
public CompletableFuture<Message> sendNewsPost(String text, Message commandMessage) {
NewsMessageModel model = NewsMessageModel
.builder()
.messageText(text)
.message(commandMessage)
.author(commandMessage.getMember())
.build();
log.info("Sending new message post based on message {}.", commandMessage.getIdLong());
Long serverId = commandMessage.getGuild().getIdLong();
MessageToSend messageToSend = templateService.renderEmbedTemplate(MESSAGE_TEMPLATE_KEY, model, serverId);
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(messageToSend, NewsPostTarget.NEWS_TARGET, serverId);
return FutureUtils.toSingleFutureGeneric(messageFutures)
.thenApply(unused -> {
Message createdMessage = messageFutures.get(0).join();
self.persistPost(commandMessage, createdMessage);
return createdMessage;
});
}
public CompletableFuture<Void> updateNewsPostViaId(Long postId, String postText, Message updatedMessage) {
NewsPost post = newsPostManagementServiceBean.getNewsPostForNewsMessageId(postId);
if(post.isLocked()) {
throw new NewsPostLockedException();
}
return updateNewsPostMessage(post, updatedMessage, postText);
}
public CompletableFuture<Void> updateNewsPost(NewsPost newsPost, Message updatedMessage) {
String contentStripped = updatedMessage.getContentRaw();
String command = contentStripped.split(" ")[0];
String postText = updatedMessage.getContentRaw().replaceFirst(command, "");
return updateNewsPostMessage(newsPost, updatedMessage, postText);
}
private CompletableFuture<Void> updateNewsPostMessage(NewsPost newsPost, Message updatedMessage, String postText) {
NewsMessageModel model = NewsMessageModel
.builder()
.messageText(postText)
.message(updatedMessage)
.author(updatedMessage.getMember())
.build();
Long serverId = updatedMessage.getGuild().getIdLong();
newsPost.setUpdated(Instant.now());
log.info("Updating news post {} with new content based on message from user {} in server {}.",
newsPost.getSourceMessageId(), updatedMessage.getIdLong(), updatedMessage.getGuild().getId());
MessageToSend messageToSend = templateService.renderEmbedTemplate(MESSAGE_TEMPLATE_KEY, model, serverId);
TextChannel newsChannel = channelService.getTextChannelFromServer(serverId, newsPost.getNewsChannel().getId());
return channelService.editMessageInAChannelFuture(messageToSend, newsChannel, newsPost.getNewsMessageId())
.thenApply(message -> null);
}
@Transactional
public void persistPost(Message commandMessage, Message createdMessage) {
log.info("Persisting news post with created message {} based on command message {}.", createdMessage.getIdLong(), commandMessage.getIdLong());
newsPostManagementServiceBean.createNewsPost(commandMessage, createdMessage);
}
}

View File

@@ -0,0 +1,77 @@
package dev.sheldan.oneplus.bot.modules.news.service.management;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.oneplus.bot.modules.news.exception.NewsPostNotFoundException;
import dev.sheldan.oneplus.bot.modules.news.model.database.NewsPost;
import dev.sheldan.oneplus.bot.modules.news.repository.NewsPostRepository;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.persistence.EntityManager;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
@Component
@Slf4j
public class NewsPostManagementServiceBean {
@Autowired
private NewsPostRepository newsPostRepository;
@Autowired
private EntityManager entityManager;
@Autowired
private UserInServerManagementService userInServerManagementService;
public NewsPost createNewsPost(Message commandMessage, Message createdMessage) {
AChannel sourceChannel = entityManager.getReference(AChannel.class, commandMessage.getChannel().getIdLong());
AChannel newsChannel = entityManager.getReference(AChannel.class, createdMessage.getChannel().getIdLong());
AUserInAServer author = userInServerManagementService.loadOrCreateUser(commandMessage.getMember());
NewsPost post = NewsPost
.builder()
.sourceChannel(sourceChannel)
.newsChannel(newsChannel)
.author(author)
.newsMessageId(createdMessage.getIdLong())
.sourceMessageId(commandMessage.getIdLong())
.server(author.getServerReference())
.locked(false)
.build();
log.debug("Created news post based on message {}.", createdMessage.getIdLong());
return newsPostRepository.save(post);
}
public Optional<NewsPost> getNewsPostForSourceMessage(Long sourceMessageId) {
return newsPostRepository.findById(sourceMessageId);
}
public Optional<NewsPost> getNewsPostForNewsMessageIdOptional(Long sourceMessageId) {
return newsPostRepository.findByNewsMessageId(sourceMessageId);
}
public NewsPost getNewsPostForNewsMessageId(Long sourceMessageId) {
return getNewsPostForNewsMessageIdOptional(sourceMessageId).orElseThrow(NewsPostNotFoundException::new);
}
public List<NewsPost> findNewsPostsOlderNotLocked(Instant pointInTime) {
log.debug("Checking for not locked news posts older than {}", pointInTime);
return newsPostRepository.findByCreatedLessThanAndLockedFalse(pointInTime);
}
public List<NewsPost> findNewsPostsUpdatedOlderThanAndLocked(Instant pointInTime) {
log.debug("Checking for not locked news posts updated older than {}.", pointInTime);
return newsPostRepository.findByUpdatedLessThanAndLockedTrue(pointInTime);
}
public void deleteNewsPosts(List<NewsPost> postsToDelete) {
log.info("Deleting {} news posts.", postsToDelete.size());
postsToDelete.forEach(newsPost -> log.info("Deleting news post {}", newsPost.getSourceMessageId()));
newsPostRepository.deleteAll(postsToDelete);
}
}

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-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../dbchangelog-3.8.xsd" >
<include file="news-tables/tables.xml" relativeToChangelogFile="true"/>
<include file="news-seedData/data.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,23 @@
<?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-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<property name="newsFeature" value="(SELECT id FROM feature WHERE key = 'news')"/>
<property name="newsModule" value="(SELECT id FROM module WHERE name = 'news')"/>
<changeSet author="Sheldan" id="news-commands" >
<insert tableName="command">
<column name="name" value="news"/>
<column name="module_id" valueComputed="${newsModule}"/>
<column name="feature_id" valueComputed="${newsFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="updateNews"/>
<column name="module_id" valueComputed="${newsModule}"/>
<column name="feature_id" valueComputed="${newsFeature}"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,13 @@
<?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-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<include file="feature.xml" relativeToChangelogFile="true"/>
<include file="module.xml" relativeToChangelogFile="true"/>
<include file="command.xml" relativeToChangelogFile="true"/>
<include file="news_jobs.xml" relativeToChangelogFile="true"/>
</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-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="news_feature-insertion">
<insert tableName="feature">
<column name="key" value="news"/>
</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-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="news-module-insertion">
<insert tableName="module">
<column name="name" value="news"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,28 @@
<?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-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="news-job-insert">
<insert tableName="scheduler_job">
<column name="name" value="newsLockJob"/>
<column name="group_name" value="news"/>
<column name="clazz" value="dev.sheldan.oneplus.bot.modules.news.job.NewsPostLockingJob"/>
<column name="active" value="true"/>
<column name="cron_expression" value="0 0 * * * ?"/>
<column name="recovery" value="false"/>
</insert>
<insert tableName="scheduler_job">
<column name="name" value="newsCleanupJob"/>
<column name="group_name" value="news"/>
<column name="clazz" value="dev.sheldan.oneplus.bot.modules.news.job.NewsPostCleanupJob"/>
<column name="active" value="true"/>
<column name="cron_expression" value="0 0 0 * * ?"/>
<column name="recovery" value="false"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,62 @@
<?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-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="news_post-table">
<createTable tableName="news_post">
<column name="source_message_id" type="BIGINT">
<constraints nullable="true" primaryKey="true" primaryKeyName="pk_news_post"/>
</column>
<column name="source_channel_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="news_channel_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="author_user_in_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="news_message_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="locked" type="boolean">
<constraints nullable="false"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
</createTable>
<addForeignKeyConstraint baseColumnNames="source_channel_id" baseTableName="news_post" constraintName="fk_news_post_source_channel"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
referencedColumnNames="id" referencedTableName="channel" validate="true"/>
<addForeignKeyConstraint baseColumnNames="news_channel_id" baseTableName="news_post" constraintName="fk_news_channel"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
referencedColumnNames="id" referencedTableName="channel" validate="true"/>
<addForeignKeyConstraint baseColumnNames="author_user_in_server_id" baseTableName="news_post" constraintName="fk_news_post_author"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="news_post" constraintName="fk_news_post_server"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
referencedColumnNames="id" referencedTableName="server" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS news_post_update_trigger ON news_post;
CREATE TRIGGER repost_check_channel_group_update_trigger BEFORE UPDATE ON news_post FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS news_post_insert_trigger ON news_post;
CREATE TRIGGER repost_check_channel_group_insert_trigger BEFORE INSERT ON news_post FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</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-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<include file="news_post.xml" relativeToChangelogFile="true"/>
</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-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog-3.8.xsd" >
<include file="1.3.9-news/collection.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,7 @@
abstracto.postTargets.news.name=news
abstracto.featureFlags.news.featureName=news
abstracto.featureFlags.news.enabled=false
abstracto.feature.news.removalDays=4
abstracto.feature.news.postLockSeconds=3600

View File

@@ -0,0 +1,24 @@
<?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>
<groupId>dev.sheldan.oneplus.bot.application</groupId>
<artifactId>application</artifactId>
<version>1.3.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>dev.sheldan.oneplus.bot.application.modules</groupId>
<artifactId>oneplus-bot-modules</artifactId>
<packaging>pom</packaging>
<modules>
<module>news</module>
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>

View File

@@ -15,6 +15,7 @@
<modules>
<module>executable</module>
<module>oneplus-bot-customizations</module>
<module>oneplus-bot-modules</module>
</modules>
<dependencyManagement>

View File

@@ -89,7 +89,7 @@
<destFileName>utility.zip</destFileName>
</artifactItem>
f <artifactItem>
<artifactItem>
<groupId>dev.sheldan.abstracto-templates.templates</groupId>
<artifactId>webservices</artifactId>
<version>${abstracto.templates.version}</version>
@@ -119,6 +119,16 @@
<destFileName>starboard-custom.zip</destFileName>
</artifactItem>
<artifactItem>
<groupId>dev.sheldan.oneplus.bot.templates.modules</groupId>
<artifactId>news-templates</artifactId>
<version>${project.version}</version>
<type>zip</type>
<overWrite>true</overWrite>
<outputDirectory>${file.basedir}/deployment/template-artifacts/</outputDirectory>
<destFileName>news.zip</destFileName>
</artifactItem>
<!-- translation artefacts -->
<artifactItem>
<groupId>dev.sheldan.abstracto-templates.translations</groupId>
@@ -206,6 +216,17 @@
<destFileName>starboard-custom.zip</destFileName>
</artifactItem>
<!-- custom -->
<artifactItem>
<groupId>dev.sheldan.oneplus.bot.templates.translations</groupId>
<artifactId>news-translations</artifactId>
<version>${project.version}</version>
<type>zip</type>
<overWrite>true</overWrite>
<outputDirectory>${file.basedir}/deployment/translation-artifacts/</outputDirectory>
<destFileName>news.zip</destFileName>
</artifactItem>
<!-- liquibase artifacts -->
<artifactItem>
<groupId>dev.sheldan.abstracto.scheduling</groupId>
@@ -307,6 +328,7 @@
<destFileName>remind.zip</destFileName>
</artifactItem>
<!-- customizations -->
<artifactItem>
<groupId>dev.sheldan.oneplus.bot.application.custom</groupId>
<artifactId>starboard-custom</artifactId>
@@ -318,6 +340,17 @@
<destFileName>starboard-custom.zip</destFileName>
</artifactItem>
<artifactItem>
<groupId>dev.sheldan.oneplus.bot.application.modules</groupId>
<artifactId>news</artifactId>
<version>${project.version}</version>
<classifier>liquibase</classifier>
<type>zip</type>
<overWrite>true</overWrite>
<outputDirectory>${file.basedir}/deployment/liquibase-artifacts/</outputDirectory>
<destFileName>news.zip</destFileName>
</artifactItem>
<!-- overrides -->
<artifactItem>

View File

@@ -1,6 +1,8 @@
{
"template_artifacts": ["utility", "core", "entertainment", "starboard", "link-embed", "webservices", "remind", "starboard-custom", "overrides-templates-webservices", "overrides-templates-core"],
"translation_artifacts": ["utility", "core", "entertainment", "starboard", "link-embed", "webservices", "remind", "starboard-custom"],
"template_artifacts": ["utility", "core", "entertainment", "starboard", "link-embed", "webservices", "remind",
"starboard-custom", "overrides-templates-webservices", "overrides-templates-core", "news"],
"translation_artifacts": ["utility", "core", "entertainment", "starboard", "link-embed", "webservices",
"remind", "starboard-custom", "news"],
"liquibase_artifacts": [
{ "zip": "scheduling", "file": "scheduling-changeLog.xml" },
{ "zip": "core", "file": "core-changeLog.xml" },
@@ -10,7 +12,8 @@
{ "zip": "webservices", "file": "webservices-changeLog.xml"},
{ "zip": "starboard", "file": "starboard-changeLog.xml"},
{ "zip": "remind", "file": "remind-changeLog.xml"},
{ "zip": "starboard-custom", "file": "starboard-custom-changeLog.xml"}
{ "zip": "starboard-custom", "file": "starboard-custom-changeLog.xml"},
{ "zip": "news", "file": "news-changeLog.xml"}
]
}

View File

@@ -19,8 +19,8 @@
<maven.compiler.source>1.8</maven.compiler.source>
<!-- edit in release.yml as well -->
<!-- when releasing a new opbot version, update the docker-compose as well-->
<abstracto.version>1.2.8</abstracto.version>
<abstracto.templates.version>1.2.4</abstracto.templates.version>
<abstracto.version>1.2.9-SNAPSHOT</abstracto.version>
<abstracto.templates.version>1.2.5-SNAPSHOT</abstracto.templates.version>
</properties>
<modules>

View File

@@ -0,0 +1,39 @@
<?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>
<groupId>dev.sheldan.oneplus.bot.templates.modules</groupId>
<artifactId>oneplus-bot-modules-templates</artifactId>
<version>1.3.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>news-templates</artifactId>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>starboard-custom-templates-${project.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,12 @@
{
<#assign roleMention="<@&823285857515470868>"/>
<#assign authorMention>${author.user.name}#${author.user.discriminator}</#assign>
"additionalMessage": "<@safe_include "news_post_description"/>",
<#if message.attachments?size gt 0>
"imageUrl": "${message.attachments[0].proxyUrl}",
</#if>
"metaConfig": {
"allowsRoleMention": true,
"preventEmptyEmbed": true
}
}

View File

@@ -0,0 +1 @@
<#include "news_post_locked_exception_message">

View File

@@ -0,0 +1 @@
<#include "news_post_not_found_exception_text">

View File

@@ -8,11 +8,12 @@
<modelVersion>4.0.0</modelVersion>
<groupId>dev.sheldan.oneplus.bot.templates.modules</groupId>
<artifactId>oneplus-bot-modules</artifactId>
<artifactId>oneplus-bot-modules-templates</artifactId>
<packaging>pom</packaging>
<version>1.3.9-SNAPSHOT</version>
<modules>
<module>starboard-custom</module>
<module>news-templates</module>
</modules>

View File

@@ -2,7 +2,7 @@
<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>
<groupId>dev.sheldan.oneplus.bot.templates.modules</groupId>
<artifactId>oneplus-bot-modules</artifactId>
<artifactId>oneplus-bot-modules-templates</artifactId>
<version>1.3.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -0,0 +1,15 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>zip</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<outputDirectory>.</outputDirectory>
<directory>${project.basedir}/src/main/resources</directory>
</fileSet>
</fileSets>
</assembly>

View File

@@ -13,5 +13,7 @@
}
],
"additionalMessage": "${definition.definition?json_string}",
"messageLimit": 1
"metaConfig": {
"messageLimit": 1
}
}

View File

@@ -8,7 +8,7 @@
</parent>
<modules>
<module>oneplus-bot-modules</module>
<module>oneplus-bot-modules-templates</module>
<module>translations</module>
<module>overrides</module>
</modules>

View File

@@ -0,0 +1,38 @@
<?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>
<groupId>dev.sheldan.oneplus.bot.templates.translations</groupId>
<artifactId>translations</artifactId>
<version>1.3.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>news-translations</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>starboard-custom-templates-${project.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,15 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>zip</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<outputDirectory>.</outputDirectory>
<directory>${project.basedir}/src/main/resources</directory>
</fileSet>
</fileSets>
</assembly>

View File

@@ -0,0 +1 @@
Posts a news post in the news channel

View File

@@ -0,0 +1,4 @@
Creates a news with the provided text and any attachments in the `news` post target with the defined template.
The news post can be updated via editing the original message containing the command or by the command `updateNews`.
This is only possible as long as the news post has not been locked. This is the case a few hours after posting it.
The news posts are completely removed from the database a few days after locking them.

View File

@@ -0,0 +1 @@
The text the news post should contain

View File

@@ -0,0 +1,4 @@
${messageText}
${roleMention?json_string}
- ${authorMention}

View File

@@ -0,0 +1 @@
Command used to update an existing news post content

View File

@@ -0,0 +1,4 @@
This command can be used to update the news post complete.
This will effectively render the template new (including author) and replace the contents of the existing news post.
Editing the news post does not re-ping any roles.
This is only possible as long as the news post was not locked and is still stored in the database.

View File

@@ -0,0 +1 @@
The ID of the news post message which was created.

View File

@@ -0,0 +1 @@
The new text the news post should receive.

View File

@@ -0,0 +1 @@
The channel in which the news should be posted in. Currently: ${currentTarget}

View File

@@ -0,0 +1 @@
Module used to post & update news in the server

View File

@@ -0,0 +1 @@
News post is locked and cannot be edited.

View File

@@ -12,5 +12,6 @@
<packaging>pom</packaging>
<modules>
<module>starboard-custom-translations</module>
<module>news-translations</module>
</modules>
</project>