mirror of
https://github.com/Sheldan/OnePlusBot.git
synced 2026-04-06 17:52:30 +00:00
[OPB-xxx] adding feature mode to fully automate news posts
This commit is contained in:
@@ -36,10 +36,24 @@ public class UpdateNews extends AbstractConditionableCommand {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandConfiguration getConfiguration() {
|
public CommandConfiguration getConfiguration() {
|
||||||
Parameter newsPostId = Parameter.builder().name("newsPostId").type(Long.class).templated(true).build();
|
Parameter newsPostId = Parameter
|
||||||
Parameter newsText = Parameter.builder().name("text").type(String.class).remainder(true).templated(true).build();
|
.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);
|
List<Parameter> parameters = Arrays.asList(newsPostId, newsText);
|
||||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
HelpInfo helpInfo = HelpInfo
|
||||||
|
.builder()
|
||||||
|
.templated(true)
|
||||||
|
.build();
|
||||||
return CommandConfiguration.builder()
|
return CommandConfiguration.builder()
|
||||||
.name("updateNews")
|
.name("updateNews")
|
||||||
.module(NewsModuleDefinition.NEWS)
|
.module(NewsModuleDefinition.NEWS)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package dev.sheldan.oneplus.bot.modules.news.config;
|
|||||||
|
|
||||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||||
import dev.sheldan.abstracto.core.config.PostTargetEnum;
|
import dev.sheldan.abstracto.core.config.PostTargetEnum;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -22,4 +23,9 @@ public class NewsFeature implements FeatureConfig {
|
|||||||
public List<PostTargetEnum> getRequiredPostTargets() {
|
public List<PostTargetEnum> getRequiredPostTargets() {
|
||||||
return Arrays.asList(NewsPostTarget.NEWS_TARGET, NewsPostTarget.FORUM_POST_NOTIFICATION);
|
return Arrays.asList(NewsPostTarget.NEWS_TARGET, NewsPostTarget.FORUM_POST_NOTIFICATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FeatureMode> getAvailableModes() {
|
||||||
|
return Arrays.asList(NewsFeatureMode.AUTOMATIC_POST, NewsFeatureMode.AUTOMATIC_PUBLISH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package dev.sheldan.oneplus.bot.modules.news.config;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum NewsFeatureMode implements FeatureMode {
|
||||||
|
AUTOMATIC_POST("automaticPost"),
|
||||||
|
AUTOMATIC_PUBLISH("automaticPublish");
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
|
||||||
|
NewsFeatureMode(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package dev.sheldan.oneplus.bot.modules.news.model;
|
||||||
|
|
||||||
|
import dev.sheldan.oneplus.bot.modules.news.model.forum.ForumPost;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
@Getter
|
||||||
|
public class ForumPostEntry {
|
||||||
|
private Long postId;
|
||||||
|
private String subject;
|
||||||
|
private String content;
|
||||||
|
private Long creatorId;
|
||||||
|
|
||||||
|
public static ForumPostEntry fromPost(ForumPost forumPost) {
|
||||||
|
return ForumPostEntry
|
||||||
|
.builder()
|
||||||
|
.postId(forumPost.getId())
|
||||||
|
.subject(forumPost.getSubject())
|
||||||
|
.content(forumPost.getContent())
|
||||||
|
.creatorId(forumPost.getSource().getUserId())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package dev.sheldan.oneplus.bot.modules.news.model;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
public class ForumPostModel {
|
||||||
|
private List<ForumPostEntry> entries;
|
||||||
|
}
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
package dev.sheldan.oneplus.bot.modules.news.service;
|
package dev.sheldan.oneplus.bot.modules.news.service;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||||
|
import dev.sheldan.oneplus.bot.modules.news.config.NewsFeatureDefinition;
|
||||||
|
import dev.sheldan.oneplus.bot.modules.news.config.NewsFeatureMode;
|
||||||
import dev.sheldan.oneplus.bot.modules.news.config.NewsPostTarget;
|
import dev.sheldan.oneplus.bot.modules.news.config.NewsPostTarget;
|
||||||
|
import dev.sheldan.oneplus.bot.modules.news.model.ForumPostEntry;
|
||||||
|
import dev.sheldan.oneplus.bot.modules.news.model.ForumPostModel;
|
||||||
import dev.sheldan.oneplus.bot.modules.news.model.ForumPostNotificationEntry;
|
import dev.sheldan.oneplus.bot.modules.news.model.ForumPostNotificationEntry;
|
||||||
import dev.sheldan.oneplus.bot.modules.news.model.ForumPostNotificationModel;
|
import dev.sheldan.oneplus.bot.modules.news.model.ForumPostNotificationModel;
|
||||||
import dev.sheldan.oneplus.bot.modules.news.model.database.NewsForumPost;
|
import dev.sheldan.oneplus.bot.modules.news.model.database.NewsForumPost;
|
||||||
@@ -13,11 +18,14 @@ import dev.sheldan.oneplus.bot.modules.news.model.forum.ForumPost;
|
|||||||
import dev.sheldan.oneplus.bot.modules.news.service.management.NewsForumPostManagementServiceBean;
|
import dev.sheldan.oneplus.bot.modules.news.service.management.NewsForumPostManagementServiceBean;
|
||||||
import dev.sheldan.oneplus.bot.modules.news.service.management.NewsSourceManagementServiceBean;
|
import dev.sheldan.oneplus.bot.modules.news.service.management.NewsSourceManagementServiceBean;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -45,7 +53,11 @@ public class NewsSourceServiceBean {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private NewsSourceServiceBean self;
|
private NewsSourceServiceBean self;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FeatureModeService featureModeService;
|
||||||
|
|
||||||
private static final String NEWS_FORUM_POST_NOTIFICATION_TEMPLATE_KEY = "newsForumPost_notification";
|
private static final String NEWS_FORUM_POST_NOTIFICATION_TEMPLATE_KEY = "newsForumPost_notification";
|
||||||
|
private static final String NEWS_FORUM_POST_TEMPLATE_KEY = "newsForumPost";
|
||||||
|
|
||||||
public void checkForNewThreads() {
|
public void checkForNewThreads() {
|
||||||
Long targetServerId = Long.parseLong(System.getenv(NEWS_FORUM_POST_NOTIFICATION_SERVER_ID_ENV_NAME));
|
Long targetServerId = Long.parseLong(System.getenv(NEWS_FORUM_POST_NOTIFICATION_SERVER_ID_ENV_NAME));
|
||||||
@@ -54,34 +66,75 @@ public class NewsSourceServiceBean {
|
|||||||
if(newForumPosts.isEmpty()) {
|
if(newForumPosts.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<ForumPostNotificationEntry> entries = new ArrayList<>();
|
|
||||||
newForumPosts.forEach(forumPost -> entries.add(ForumPostNotificationEntry.fromPost(forumPost)));
|
|
||||||
|
|
||||||
ForumPostNotificationModel model = ForumPostNotificationModel
|
if(featureModeService.featureModeActive(NewsFeatureDefinition.NEWS, targetServerId, NewsFeatureMode.AUTOMATIC_POST)) {
|
||||||
.builder()
|
List<ForumPostEntry> entries = new ArrayList<>();
|
||||||
.entries(entries)
|
newForumPosts.forEach(forumPost -> entries.add(ForumPostEntry.fromPost(forumPost)));
|
||||||
.build();
|
ForumPostModel model = ForumPostModel
|
||||||
|
.builder()
|
||||||
|
.entries(entries)
|
||||||
|
.build();
|
||||||
|
MessageToSend messageToSend = templateService.renderEmbedTemplate(NEWS_FORUM_POST_TEMPLATE_KEY, model, targetServerId);
|
||||||
|
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(messageToSend, NewsPostTarget.NEWS_TARGET, targetServerId);
|
||||||
|
FutureUtils.toSingleFutureGeneric(messageFutures)
|
||||||
|
.thenAccept(unused -> {
|
||||||
|
log.info("Sent news forum post notification.");
|
||||||
|
List<Pair<Long, Long>> posts = entries
|
||||||
|
.stream()
|
||||||
|
.map(forumPostNotificationEntry -> Pair.of(forumPostNotificationEntry.getCreatorId(), forumPostNotificationEntry.getPostId()))
|
||||||
|
.toList();
|
||||||
|
self.persistForumPostsAndThreadCount(posts);
|
||||||
|
self.handleAutomaticPublish(messageFutures, targetServerId);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
List<ForumPostNotificationEntry> entries = new ArrayList<>();
|
||||||
|
newForumPosts.forEach(forumPost -> entries.add(ForumPostNotificationEntry.fromPost(forumPost)));
|
||||||
|
ForumPostNotificationModel model = ForumPostNotificationModel
|
||||||
|
.builder()
|
||||||
|
.entries(entries)
|
||||||
|
.build();
|
||||||
|
MessageToSend messageToSend = templateService.renderEmbedTemplate(NEWS_FORUM_POST_NOTIFICATION_TEMPLATE_KEY, model, targetServerId);
|
||||||
|
FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(messageToSend, NewsPostTarget.FORUM_POST_NOTIFICATION, targetServerId))
|
||||||
|
.thenAccept(unused -> {
|
||||||
|
log.info("Sent news forum post notification.");
|
||||||
|
List<Pair<Long, Long>> posts = entries
|
||||||
|
.stream()
|
||||||
|
.map(forumPostNotificationEntry -> Pair.of(forumPostNotificationEntry.getCreatorId(), forumPostNotificationEntry.getPostId()))
|
||||||
|
.toList();
|
||||||
|
self.persistForumPostsAndThreadCount(posts);
|
||||||
|
}).exceptionally(throwable -> {
|
||||||
|
log.error("Failed to send news forum post notification.", throwable);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(NEWS_FORUM_POST_NOTIFICATION_TEMPLATE_KEY, model, targetServerId);
|
|
||||||
|
|
||||||
FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(messageToSend, NewsPostTarget.FORUM_POST_NOTIFICATION, targetServerId))
|
|
||||||
.thenAccept(unused -> {
|
|
||||||
log.info("Sent news forum post notification.");
|
|
||||||
self.persistForumPostsAndThreadCount(entries);
|
|
||||||
}).exceptionally(throwable -> {
|
|
||||||
log.error("Failed to send news forum post notification.", throwable);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void persistForumPostsAndThreadCount(List<ForumPostNotificationEntry> entries) {
|
public CompletableFuture<Message> handleAutomaticPublish(List<CompletableFuture<Message>> messageFutures, Long serverId) {
|
||||||
|
if(featureModeService.featureModeActive(NewsFeatureDefinition.NEWS, serverId, NewsFeatureMode.AUTOMATIC_PUBLISH)) {
|
||||||
|
if(messageFutures != null && !messageFutures.isEmpty() && messageFutures.get(0) != null) {
|
||||||
|
Message newsMessage = messageFutures.get(0).join();
|
||||||
|
log.info("Publishing message {} in server {}.", newsMessage.getId(), serverId);
|
||||||
|
return newsMessage.crosspost().submit();
|
||||||
|
} else {
|
||||||
|
log.info("No message found - not cross posting.");
|
||||||
|
return CompletableFuture.completedFuture(null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.info("Automatic publishing disabled in server {}.", serverId);
|
||||||
|
return CompletableFuture.completedFuture(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void persistForumPostsAndThreadCount(List<Pair<Long, Long>> posts) {
|
||||||
Map<Long, NewsSource> sourceMap = newsSourceManagementServiceBean.loadNewsSources()
|
Map<Long, NewsSource> sourceMap = newsSourceManagementServiceBean.loadNewsSources()
|
||||||
.stream()
|
.stream()
|
||||||
.collect(Collectors.toMap(NewsSource::getUserId, Function.identity()));
|
.collect(Collectors.toMap(NewsSource::getUserId, Function.identity()));
|
||||||
|
|
||||||
entries.forEach(forumPostNotificationEntry ->
|
posts.forEach(forumPostNotificationEntry ->
|
||||||
newsForumPostManagementServiceBean.createPost(sourceMap.get(forumPostNotificationEntry.getCreatorId()), forumPostNotificationEntry.getPostId()));
|
newsForumPostManagementServiceBean.createPost(sourceMap.get(forumPostNotificationEntry.getLeft()), forumPostNotificationEntry.getRight()));
|
||||||
|
|
||||||
sourceMap.values().forEach(newsSource -> {
|
sourceMap.values().forEach(newsSource -> {
|
||||||
Long currentThreadCount = forumApiClient.getCurrentThreadCount(newsSource);
|
Long currentThreadCount = forumApiClient.getCurrentThreadCount(newsSource);
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ abstracto.featureFlags.news.enabled=false
|
|||||||
abstracto.feature.news.removalDays=4
|
abstracto.feature.news.removalDays=4
|
||||||
abstracto.feature.news.postLockSeconds=3600
|
abstracto.feature.news.postLockSeconds=3600
|
||||||
|
|
||||||
|
abstracto.featureModes.automaticPublish.featureName=news
|
||||||
|
abstracto.featureModes.automaticPublish.mode=automaticPublish
|
||||||
|
abstracto.featureModes.automaticPublish.enabled=false
|
||||||
|
|
||||||
|
abstracto.featureModes.automaticPost.featureName=news
|
||||||
|
abstracto.featureModes.automaticPost.mode=automaticPost
|
||||||
|
abstracto.featureModes.automaticPost.enabled=false
|
||||||
|
|
||||||
abstracto.feature.news.userURL=https://community.oneplus.com/ajax/user/frontend/user/info?uid=%s
|
abstracto.feature.news.userURL=https://community.oneplus.com/ajax/user/frontend/user/info?uid=%s
|
||||||
# TODO support pagination.. eventually
|
# TODO support pagination.. eventually
|
||||||
abstracto.feature.news.threadURL=https://community.oneplus.com/ajax/user/frontend/thread/page?page=1&limit=100&uid=%s
|
abstracto.feature.news.threadURL=https://community.oneplus.com/ajax/user/frontend/thread/page?page=1&limit=100&uid=%s
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
<#assign roleMention="<@&479202891358535681>"/>
|
||||||
|
"additionalMessage": "${roleMention}",
|
||||||
|
"embeds": [
|
||||||
|
{
|
||||||
|
<#macro postDisplay post>
|
||||||
|
${post.subject?json_string}
|
||||||
|
https://community.oneplus.com/thread/${post.postId?c}
|
||||||
|
|
||||||
|
</#macro>
|
||||||
|
"description": "<#list entries as entry><@postDisplay post=entry /></#list>"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messageConfig": {
|
||||||
|
"allowsRoleMention": true
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user