mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-04-20 05:24:09 +00:00
added some utility methods to bot service
reworked message cache to not be jda messages, but own objects: cachedMessages, jda messages should not be kept around added listener to listen for message links, to represent them in an embed (or embeds) added offsetDateTime handling for gson introduced a way on how to handle async transaction handling for suggestions and message loading (self reference with another method with transactional) added timestamp support to embeds
This commit is contained in:
@@ -1,11 +1,13 @@
|
|||||||
package dev.sheldan.abstracto.moderation.listener;
|
package dev.sheldan.abstracto.moderation.listener;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||||
import dev.sheldan.abstracto.core.utils.ContextUtils;
|
import dev.sheldan.abstracto.core.utils.ContextUtils;
|
||||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||||
import dev.sheldan.abstracto.moderation.models.template.listener.MessageDeletedAttachmentLog;
|
import dev.sheldan.abstracto.moderation.models.template.listener.MessageDeletedAttachmentLog;
|
||||||
import dev.sheldan.abstracto.moderation.models.template.listener.MessageDeletedLog;
|
import dev.sheldan.abstracto.moderation.models.template.listener.MessageDeletedLog;
|
||||||
import dev.sheldan.abstracto.templating.TemplateService;
|
import dev.sheldan.abstracto.templating.TemplateService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageDeleteEvent;
|
import net.dv8tion.jda.api.events.message.guild.GuildMessageDeleteEvent;
|
||||||
@@ -15,8 +17,10 @@ import org.springframework.stereotype.Component;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@Slf4j
|
||||||
public class MessageDeletedListener extends ListenerAdapter {
|
public class MessageDeletedListener extends ListenerAdapter {
|
||||||
|
|
||||||
private static final String DELETE_LOG_TARGET = "deleteLog";
|
private static final String DELETE_LOG_TARGET = "deleteLog";
|
||||||
@@ -38,18 +42,22 @@ public class MessageDeletedListener extends ListenerAdapter {
|
|||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void onGuildMessageDelete(@Nonnull GuildMessageDeleteEvent event) {
|
public void onGuildMessageDelete(@Nonnull GuildMessageDeleteEvent event) {
|
||||||
Message messageFromCache = messageCache.getMessageFromCache(event.getMessageIdLong(),
|
CachedMessage messageFromCache = null;
|
||||||
event.getChannel().getIdLong(), event.getGuild().getIdLong());
|
try {
|
||||||
|
messageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong());
|
||||||
|
} catch (ExecutionException | InterruptedException e) {
|
||||||
|
log.warn("Failed to load message.", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
MessageDeletedLog logModel = (MessageDeletedLog) contextUtils.fromMessage(messageFromCache, MessageDeletedLog.class);
|
MessageDeletedLog logModel = (MessageDeletedLog) contextUtils.fromMessage(messageFromCache, MessageDeletedLog.class);
|
||||||
logModel.setMessage(messageFromCache);
|
logModel.setMessage(messageFromCache);
|
||||||
String simpleMessageUpdatedMessage = templateService.renderTemplate(MESSAGE_DELETED_TEMPLATE, logModel);
|
String simpleMessageUpdatedMessage = templateService.renderTemplate(MESSAGE_DELETED_TEMPLATE, logModel);
|
||||||
postTargetService.sendTextInPostTarget(simpleMessageUpdatedMessage, DELETE_LOG_TARGET, event.getGuild().getIdLong());
|
postTargetService.sendTextInPostTarget(simpleMessageUpdatedMessage, DELETE_LOG_TARGET, event.getGuild().getIdLong());
|
||||||
MessageEmbed embed = templateService.renderEmbedTemplate(MESSAGE_DELETED_TEMPLATE, logModel);
|
MessageEmbed embed = templateService.renderEmbedTemplate(MESSAGE_DELETED_TEMPLATE, logModel);
|
||||||
postTargetService.sendEmbedInPostTarget(embed, DELETE_LOG_TARGET, event.getGuild().getIdLong());
|
postTargetService.sendEmbedInPostTarget(embed, DELETE_LOG_TARGET, event.getGuild().getIdLong());
|
||||||
for (int i = 0; i < messageFromCache.getAttachments().size(); i++) {
|
for (int i = 0; i < messageFromCache.getAttachmentUrls().size(); i++) {
|
||||||
Message.Attachment attachment = messageFromCache.getAttachments().get(i);
|
|
||||||
MessageDeletedAttachmentLog log = (MessageDeletedAttachmentLog) contextUtils.fromMessage(messageFromCache, MessageDeletedAttachmentLog.class);
|
MessageDeletedAttachmentLog log = (MessageDeletedAttachmentLog) contextUtils.fromMessage(messageFromCache, MessageDeletedAttachmentLog.class);
|
||||||
log.setImageUrl(attachment.getProxyUrl());
|
log.setImageUrl(messageFromCache.getAttachmentUrls().get(i));
|
||||||
log.setCounter(i + 1);
|
log.setCounter(i + 1);
|
||||||
MessageEmbed attachmentEmbed = templateService.renderEmbedTemplate(MESSAGE_DELETED_ATTACHMENT_TEMPLATE, log);
|
MessageEmbed attachmentEmbed = templateService.renderEmbedTemplate(MESSAGE_DELETED_ATTACHMENT_TEMPLATE, log);
|
||||||
postTargetService.sendEmbedInPostTarget(attachmentEmbed, DELETE_LOG_TARGET, event.getGuild().getIdLong());
|
postTargetService.sendEmbedInPostTarget(attachmentEmbed, DELETE_LOG_TARGET, event.getGuild().getIdLong());
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package dev.sheldan.abstracto.moderation.listener;
|
package dev.sheldan.abstracto.moderation.listener;
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.MessageTextUpdatedListener;
|
import dev.sheldan.abstracto.core.MessageTextUpdatedListener;
|
||||||
|
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||||
import dev.sheldan.abstracto.moderation.models.template.listener.MessageEditedLog;
|
import dev.sheldan.abstracto.moderation.models.template.listener.MessageEditedLog;
|
||||||
@@ -30,8 +31,8 @@ public class MessageEditedListener implements MessageTextUpdatedListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void execute(Message messageBefore, Message messageAfter) {
|
public void execute(CachedMessage messageBefore, Message messageAfter) {
|
||||||
if(messageBefore.getContentRaw().equals(messageAfter.getContentRaw())){
|
if(messageBefore.getContent().equals(messageAfter.getContentRaw())){
|
||||||
log.debug("Message content was the same. Possible reason was: message was not in cache.");
|
log.debug("Message content was the same. Possible reason was: message was not in cache.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -45,7 +46,7 @@ public class MessageEditedListener implements MessageTextUpdatedListener {
|
|||||||
String simpleMessageUpdatedMessage = templateService.renderTemplate(MESSAGE_EDITED_TEMPLATE, log);
|
String simpleMessageUpdatedMessage = templateService.renderTemplate(MESSAGE_EDITED_TEMPLATE, log);
|
||||||
postTargetService.sendTextInPostTarget(simpleMessageUpdatedMessage, EDIT_LOG_TARGET, messageAfter.getGuild().getIdLong());
|
postTargetService.sendTextInPostTarget(simpleMessageUpdatedMessage, EDIT_LOG_TARGET, messageAfter.getGuild().getIdLong());
|
||||||
MessageEmbed embed = templateService.renderEmbedTemplate(MESSAGE_EDITED_TEMPLATE, log);
|
MessageEmbed embed = templateService.renderEmbedTemplate(MESSAGE_EDITED_TEMPLATE, log);
|
||||||
postTargetService.sendEmbedInPostTarget(embed, EDIT_LOG_TARGET, messageBefore.getGuild().getIdLong());
|
postTargetService.sendEmbedInPostTarget(embed, EDIT_LOG_TARGET, messageBefore.getServerId());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,12 +41,8 @@ public class BanServiceBean implements BanService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void banUser(Long guildId, Long userId, String reason) {
|
private void banUser(Long guildId, Long userId, String reason) {
|
||||||
Guild guildById = bot.getInstance().getGuildById(guildId);
|
Guild guildById = bot.getGuildById(guildId);
|
||||||
if(guildById != null) {
|
log.info("Banning user {} in guild {}.", userId, guildId);
|
||||||
log.info("Banning user {} in guild {}.", userId, guildId);
|
guildById.ban(userId.toString(), 0, reason).queue();
|
||||||
guildById.ban(userId.toString(), 0, reason).queue();
|
|
||||||
} else {
|
|
||||||
log.warn("Guild id {} from member was not found.", guildId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,13 +27,9 @@ public class KickServiceBean implements KickService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void kickMember(Member member, String reason, KickLogModel kickLogModel) {
|
public void kickMember(Member member, String reason, KickLogModel kickLogModel) {
|
||||||
Guild guildById = bot.getInstance().getGuildById(member.getGuild().getIdLong());
|
Guild guildById = bot.getGuildById(kickLogModel.getGuild().getIdLong());
|
||||||
if(guildById != null) {
|
guildById.kick(member, reason).queue();
|
||||||
guildById.kick(member, reason).queue();
|
this.sendKickLog(kickLogModel);
|
||||||
this.sendKickLog(kickLogModel);
|
|
||||||
} else {
|
|
||||||
log.warn("Failed to kick member {} from guild {}. Guild was not found.", member.getId(), member.getGuild().getId());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendKickLog(KickLogModel kickLogModel) {
|
private void sendKickLog(KickLogModel kickLogModel) {
|
||||||
|
|||||||
@@ -29,17 +29,7 @@ public class SlowModeServiceBean implements SlowModeService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSlowMode(AChannel channel, Duration duration) {
|
public void setSlowMode(AChannel channel, Duration duration) {
|
||||||
JDA jpaInstance = bot.getInstance();
|
TextChannel textChannel = bot.getTextChannelFromServer(channel.getServer().getId(), channel.getId());
|
||||||
Guild guild = jpaInstance.getGuildById(channel.getServer().getId());
|
this.setSlowMode(textChannel, duration);
|
||||||
if(guild != null) {
|
|
||||||
TextChannel textChannelById = guild.getTextChannelById(channel.getId());
|
|
||||||
if(textChannelById != null) {
|
|
||||||
this.setSlowMode(textChannelById, duration);
|
|
||||||
} else {
|
|
||||||
log.warn("Channel {} was not found in guild {} when trying to set a slow mode.", channel.getId(), channel.getServer().getId());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("Guild {} was not found when trying to set slow mode.", channel.getServer().getId());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public class WarnServiceBean implements WarnService {
|
|||||||
Warning warning = warnManagementService.createWarning(warnedAUserInAServer, warningAUserInAServer, reason);
|
Warning warning = warnManagementService.createWarning(warnedAUserInAServer, warningAUserInAServer, reason);
|
||||||
JDA instance = bot.getInstance();
|
JDA instance = bot.getInstance();
|
||||||
User userBeingWarned = instance.getUserById(warnedAUser.getId());
|
User userBeingWarned = instance.getUserById(warnedAUser.getId());
|
||||||
Guild guildById = instance.getGuildById(serverOfWarning.getId());
|
Guild guildById = bot.getGuildById(serverOfWarning.getId());
|
||||||
String guildName = "<defaultName>";
|
String guildName = "<defaultName>";
|
||||||
if(guildById != null) {
|
if(guildById != null) {
|
||||||
guildName = guildById.getName();
|
guildName = guildById.getName();
|
||||||
|
|||||||
@@ -12,11 +12,11 @@
|
|||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"name": ":x: Original Message: ",
|
"name": ":x: Original Message: ",
|
||||||
"value": "${message.contentRaw}"
|
"value": "${message.content}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Link",
|
"name": "Link",
|
||||||
"value": "[${textChannel.name}](${message.jumpUrl})"
|
"value": "[${textChannel.name}](${message.messageUrl})"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
Message from ${member.effectiveName} (${member.idLong?c}) deleted in ${textChannel.asMention}.
|
Message from ${member.effectiveName} (${member.idLong?c}) deleted in ${textChannel.asMention}.
|
||||||
Message: ${message.contentRaw}
|
Message: ${message.content}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package dev.sheldan.abstracto.moderation.models.template.listener;
|
package dev.sheldan.abstracto.moderation.models.template.listener;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||||
import dev.sheldan.abstracto.core.models.UserInitiatedServerContext;
|
import dev.sheldan.abstracto.core.models.UserInitiatedServerContext;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.experimental.SuperBuilder;
|
import lombok.experimental.SuperBuilder;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
|
||||||
|
|
||||||
@Getter @Setter @SuperBuilder
|
@Getter @Setter @SuperBuilder
|
||||||
public class MessageDeletedLog extends UserInitiatedServerContext {
|
public class MessageDeletedLog extends UserInitiatedServerContext {
|
||||||
private Message message;
|
private CachedMessage message;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package dev.sheldan.abstracto.moderation.models.template.listener;
|
package dev.sheldan.abstracto.moderation.models.template.listener;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||||
import dev.sheldan.abstracto.core.models.UserInitiatedServerContext;
|
import dev.sheldan.abstracto.core.models.UserInitiatedServerContext;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@@ -9,5 +10,5 @@ import net.dv8tion.jda.api.entities.Message;
|
|||||||
@Getter @Setter @SuperBuilder
|
@Getter @Setter @SuperBuilder
|
||||||
public class MessageEditedLog extends UserInitiatedServerContext {
|
public class MessageEditedLog extends UserInitiatedServerContext {
|
||||||
private Message messageAfter;
|
private Message messageAfter;
|
||||||
private Message messageBefore;
|
private CachedMessage messageBefore;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,16 @@ import dev.sheldan.abstracto.templating.TemplateService;
|
|||||||
import dev.sheldan.abstracto.utility.models.Suggestion;
|
import dev.sheldan.abstracto.utility.models.Suggestion;
|
||||||
import dev.sheldan.abstracto.utility.models.SuggestionState;
|
import dev.sheldan.abstracto.utility.models.SuggestionState;
|
||||||
import dev.sheldan.abstracto.utility.models.template.SuggestionLog;
|
import dev.sheldan.abstracto.utility.models.template.SuggestionLog;
|
||||||
import dev.sheldan.abstracto.utility.service.management.AsyncSuggestionServiceBean;
|
|
||||||
import dev.sheldan.abstracto.utility.service.management.SuggestionManagementService;
|
import dev.sheldan.abstracto.utility.service.management.SuggestionManagementService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.dv8tion.jda.api.JDA;
|
import net.dv8tion.jda.api.JDA;
|
||||||
import net.dv8tion.jda.api.entities.*;
|
import net.dv8tion.jda.api.entities.*;
|
||||||
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.Propagation;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -38,15 +41,15 @@ public class SuggestionServiceBean implements SuggestionService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private Bot botService;
|
private Bot botService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private AsyncSuggestionServiceBean suggestionServiceBean;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private EmoteManagementService emoteManagementService;
|
private EmoteManagementService emoteManagementService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MessageService messageService;
|
private MessageService messageService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SuggestionServiceBean self;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createSuggestion(Member member, String text, SuggestionLog suggestionLog) {
|
public void createSuggestion(Member member, String text, SuggestionLog suggestionLog) {
|
||||||
Suggestion suggestion = suggestionManagementService.createSuggestion(member, text);
|
Suggestion suggestion = suggestionManagementService.createSuggestion(member, text);
|
||||||
@@ -93,13 +96,25 @@ public class SuggestionServiceBean implements SuggestionService {
|
|||||||
TextChannel textChannelById = guildById.getTextChannelById(channelId);
|
TextChannel textChannelById = guildById.getTextChannelById(channelId);
|
||||||
if(textChannelById != null) {
|
if(textChannelById != null) {
|
||||||
textChannelById.retrieveMessageById(originalMessageId).queue(message -> {
|
textChannelById.retrieveMessageById(originalMessageId).queue(message -> {
|
||||||
suggestionServiceBean.updateSuggestionMessageText(text, suggestionLog, message);
|
self.updateSuggestionMessageText(text, suggestionLog, message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||||
|
public void updateSuggestionMessageText(String text, SuggestionLog suggestionLog, Message message) {
|
||||||
|
Optional<MessageEmbed> embedOptional = message.getEmbeds().stream().filter(embed -> embed.getDescription() != null).findFirst();
|
||||||
|
if(embedOptional.isPresent()) {
|
||||||
|
MessageEmbed suggestionEmbed = embedOptional.get();
|
||||||
|
suggestionLog.setReason(text);
|
||||||
|
suggestionLog.setText(suggestionEmbed.getDescription());
|
||||||
|
MessageEmbed embed = templateService.renderEmbedTemplate(SUGGESTION_LOG_TEMPLATE, suggestionLog);
|
||||||
|
postTargetService.sendEmbedInPostTarget(embed, SUGGESTIONS_TARGET, suggestionLog.getServer().getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rejectSuggestion(Long suggestionId, String text, SuggestionLog log) {
|
public void rejectSuggestion(Long suggestionId, String text, SuggestionLog log) {
|
||||||
Suggestion suggestion = suggestionManagementService.getSuggestion(suggestionId);
|
Suggestion suggestion = suggestionManagementService.getSuggestion(suggestionId);
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.utility.service.management;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
|
||||||
import dev.sheldan.abstracto.templating.TemplateService;
|
|
||||||
import dev.sheldan.abstracto.utility.models.template.SuggestionLog;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
|
||||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static dev.sheldan.abstracto.utility.service.SuggestionServiceBean.SUGGESTION_LOG_TEMPLATE;
|
|
||||||
import static dev.sheldan.abstracto.utility.service.SuggestionServiceBean.SUGGESTIONS_TARGET;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@Slf4j
|
|
||||||
public class AsyncSuggestionServiceBean {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TemplateService templateService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private PostTargetService postTargetService;
|
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
|
||||||
public void updateSuggestionMessageText(String text, SuggestionLog suggestionLog, Message message) {
|
|
||||||
Optional<MessageEmbed> embedOptional = message.getEmbeds().stream().filter(embed -> embed.getDescription() != null).findFirst();
|
|
||||||
if(embedOptional.isPresent()) {
|
|
||||||
MessageEmbed suggestionEmbed = embedOptional.get();
|
|
||||||
suggestionLog.setReason(text);
|
|
||||||
suggestionLog.setText(suggestionEmbed.getDescription());
|
|
||||||
MessageEmbed embed = templateService.renderEmbedTemplate(SUGGESTION_LOG_TEMPLATE, suggestionLog);
|
|
||||||
postTargetService.sendEmbedInPostTarget(embed, SUGGESTIONS_TARGET, suggestionLog.getServer().getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -98,6 +98,11 @@
|
|||||||
<artifactId>caffeine</artifactId>
|
<artifactId>caffeine</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package dev.sheldan.abstracto.config;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class CoreConfig {
|
||||||
|
@Bean
|
||||||
|
public Gson gson() {
|
||||||
|
return new GsonBuilder()
|
||||||
|
.registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeAdapter())
|
||||||
|
.setPrettyPrinting().create();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package dev.sheldan.abstracto.config;
|
||||||
|
|
||||||
|
import com.google.gson.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.temporal.TemporalAccessor;
|
||||||
|
|
||||||
|
public class OffsetDateTimeAdapter implements JsonDeserializer<OffsetDateTime> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OffsetDateTime deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
|
||||||
|
TemporalAccessor ta = DateTimeFormatter.ISO_INSTANT.parse(jsonElement.getAsString());
|
||||||
|
Instant i = Instant.from(ta);
|
||||||
|
return OffsetDateTime.ofInstant(i, ZoneId.systemDefault());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
package dev.sheldan.abstracto.core.service;
|
package dev.sheldan.abstracto.core.service;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.ServerChannelUser;
|
||||||
import net.dv8tion.jda.api.JDA;
|
import net.dv8tion.jda.api.JDA;
|
||||||
import net.dv8tion.jda.api.JDABuilder;
|
import net.dv8tion.jda.api.JDABuilder;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.TextChannel;
|
||||||
import net.dv8tion.jda.api.utils.cache.CacheFlag;
|
import net.dv8tion.jda.api.utils.cache.CacheFlag;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -28,6 +32,50 @@ public class BotService implements Bot {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerChannelUser getServerChannelUser(Long serverId, Long channelId, Long userId) {
|
||||||
|
TextChannel textChannelById = getTextChannelFromServer(serverId, channelId);
|
||||||
|
Guild guildById = getGuildById(serverId);
|
||||||
|
if(textChannelById != null) {
|
||||||
|
Member member = guildById.getMemberById(userId);
|
||||||
|
return ServerChannelUser.builder().guild(guildById).textChannel(textChannelById).member(member).build();
|
||||||
|
}
|
||||||
|
throw new RuntimeException(String.format("Member %s or text channel %s not found in guild %s", userId, channelId, serverId));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Member getMemberInServer(Long serverId, Long memberId) {
|
||||||
|
Guild guildById = instance.getGuildById(serverId);
|
||||||
|
if(guildById != null) {
|
||||||
|
return guildById.getMemberById(memberId);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException(String.format("Member %s not found in guild %s", memberId, serverId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextChannel getTextChannelFromServer(Long serverId, Long textChannelId) {
|
||||||
|
Guild guild = getGuildById(serverId);
|
||||||
|
TextChannel textChannelById = guild.getTextChannelById(textChannelId);
|
||||||
|
if(textChannelById != null) {
|
||||||
|
return textChannelById;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException(String.format("Text channel %s in guild %s not found", textChannelId, serverId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Guild getGuildById(Long serverId) {
|
||||||
|
Guild guildById = instance.getGuildById(serverId);
|
||||||
|
if(guildById != null) {
|
||||||
|
return guildById;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException(String.format("Guild %s not found", serverId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package dev.sheldan.abstracto.core.service;
|
package dev.sheldan.abstracto.core.service;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||||
|
import dev.sheldan.abstracto.core.models.embed.*;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
import net.dv8tion.jda.api.entities.TextChannel;
|
import net.dv8tion.jda.api.entities.TextChannel;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.cache.annotation.CacheConfig;
|
import org.springframework.cache.annotation.CacheConfig;
|
||||||
@@ -10,6 +12,12 @@ import org.springframework.cache.annotation.CachePut;
|
|||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
@Component @Slf4j
|
@Component @Slf4j
|
||||||
@CacheConfig(cacheNames = {"messages"})
|
@CacheConfig(cacheNames = {"messages"})
|
||||||
public class MessageCacheBean implements MessageCache {
|
public class MessageCacheBean implements MessageCache {
|
||||||
@@ -19,38 +27,110 @@ public class MessageCacheBean implements MessageCache {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CachePut(key = "#message.id")
|
@CachePut(key = "#message.id")
|
||||||
public Message putMessageInCache(Message message) {
|
public CachedMessage putMessageInCache(Message message) {
|
||||||
log.debug("Adding message {} to cache", message.getId());
|
log.debug("Adding message {} to cache", message.getId());
|
||||||
|
return buildCachedMessageFromMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@CachePut(key = "#message.messageId")
|
||||||
|
public CachedMessage putMessageInCache(CachedMessage message) {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(key = "#message.id")
|
public CachedMessage getMessageFromCache(Message message) throws ExecutionException, InterruptedException {
|
||||||
public Message getMessageFromCache(Message message) {
|
|
||||||
log.debug("Retrieving message {}", message.getId());
|
log.debug("Retrieving message {}", message.getId());
|
||||||
return getMessageInTextChannelOfGuild(message.getIdLong(), message.getTextChannel().getIdLong(), message.getGuild().getIdLong());
|
return getMessageFromCache(message.getGuild().getIdLong(), message.getChannel().getIdLong(), message.getIdLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(key = "#messageId.toString()")
|
@Cacheable(key = "#messageId.toString()")
|
||||||
public Message getMessageFromCache(Long messageId, Long textChannelId, Long guildId) {
|
public CachedMessage getMessageFromCache(Long guildId, Long textChannelId, Long messageId) throws ExecutionException, InterruptedException {
|
||||||
log.info("Retrieving message with parameters");
|
log.info("Retrieving message with parameters");
|
||||||
return getMessageInTextChannelOfGuild(messageId, textChannelId, guildId);
|
|
||||||
|
CompletableFuture<CachedMessage> cachedMessageCompletableFuture =
|
||||||
|
getMessage(guildId, textChannelId, messageId)
|
||||||
|
.thenApply(jdaMessage -> {
|
||||||
|
CachedMessage cachedMessage = buildCachedMessageFromMessage(jdaMessage);
|
||||||
|
putMessageInCache(cachedMessage);
|
||||||
|
return cachedMessage;
|
||||||
|
});
|
||||||
|
|
||||||
|
return cachedMessageCompletableFuture.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Message getMessageInTextChannelOfGuild(Long messageId, Long textChannelId, Long guildId) {
|
@Override
|
||||||
Guild guildById = bot.getInstance().getGuildById(guildId);
|
public CompletableFuture<Message> getMessage(Long guildId, Long textChannelId, Long messageId) {
|
||||||
if(guildById != null) {
|
TextChannel textChannelById = bot.getTextChannelFromServer(guildId, textChannelId);
|
||||||
TextChannel textChannelById = guildById.getTextChannelById(textChannelId);
|
return textChannelById.retrieveMessageById(messageId).submit();
|
||||||
if(textChannelById != null) {
|
}
|
||||||
return textChannelById.retrieveMessageById(messageId).complete();
|
|
||||||
} else {
|
private CachedMessage buildCachedMessageFromMessage(Message message) {
|
||||||
log.warn("Failed to load text channel {} of message {} in guild {}", textChannelId, messageId, guildId);
|
List<String> attachmentUrls = new ArrayList<>();
|
||||||
}
|
message.getAttachments().forEach(attachment -> {
|
||||||
} else {
|
attachmentUrls.add(attachment.getProxyUrl());
|
||||||
log.warn("Failed to guild {} of message {}", guildId, messageId);
|
});
|
||||||
|
List<CachedEmbed> embeds = new ArrayList<>();
|
||||||
|
message.getEmbeds().forEach(embed -> {
|
||||||
|
embeds.add(getCachedEmbedFromEmbed(embed));
|
||||||
|
});
|
||||||
|
return CachedMessage.builder()
|
||||||
|
.authorId(message.getAuthor().getIdLong())
|
||||||
|
.serverId(message.getGuild().getIdLong())
|
||||||
|
.channelId(message.getChannel().getIdLong())
|
||||||
|
.content(message.getContentRaw())
|
||||||
|
.embeds(embeds)
|
||||||
|
.timeCreated(message.getTimeCreated())
|
||||||
|
.attachmentUrls(attachmentUrls)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private CachedEmbed getCachedEmbedFromEmbed(MessageEmbed embed) {
|
||||||
|
CachedEmbed.CachedEmbedBuilder builder = CachedEmbed
|
||||||
|
.builder();
|
||||||
|
MessageEmbed.AuthorInfo author = embed.getAuthor();
|
||||||
|
if(author != null) {
|
||||||
|
builder.author(EmbedAuthor.builder().avatar(author.getProxyIconUrl()).url(author.getUrl()).name(author.getName()).build());
|
||||||
|
}
|
||||||
|
List<MessageEmbed.Field> fields = embed.getFields();
|
||||||
|
if(!fields.isEmpty()) {
|
||||||
|
List<EmbedField> embedFields = new ArrayList<>();
|
||||||
|
fields.forEach(field -> {
|
||||||
|
EmbedField build = EmbedField
|
||||||
|
.builder()
|
||||||
|
.name(field.getName())
|
||||||
|
.value(field.getValue())
|
||||||
|
.inline(field.isInline())
|
||||||
|
.build();
|
||||||
|
embedFields.add(build);
|
||||||
|
});
|
||||||
|
builder.fields(embedFields);
|
||||||
|
}
|
||||||
|
MessageEmbed.ImageInfo image = embed.getImage();
|
||||||
|
if(image != null) {
|
||||||
|
builder.imageUrl(image.getProxyUrl());
|
||||||
|
}
|
||||||
|
Color color = embed.getColor();
|
||||||
|
if(color != null) {
|
||||||
|
EmbedColor build = EmbedColor
|
||||||
|
.builder()
|
||||||
|
.r(color.getRed())
|
||||||
|
.g(color.getGreen())
|
||||||
|
.b(color.getBlue())
|
||||||
|
.build();
|
||||||
|
builder.color(build);
|
||||||
|
}
|
||||||
|
builder.description(embed.getDescription());
|
||||||
|
MessageEmbed.Footer footer = embed.getFooter();
|
||||||
|
if(footer != null) {
|
||||||
|
EmbedFooter build = EmbedFooter
|
||||||
|
.builder()
|
||||||
|
.icon(footer.getProxyIconUrl())
|
||||||
|
.text(footer.getText())
|
||||||
|
.build();
|
||||||
|
builder.footer(build);
|
||||||
}
|
}
|
||||||
throw new RuntimeException("Message was not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,21 +21,17 @@ public class MessageServiceBean implements MessageService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addReactionToMessage(String emoteKey, Long serverId, Message message) {
|
public void addReactionToMessage(String emoteKey, Long serverId, Message message) {
|
||||||
Guild guildById = bot.getInstance().getGuildById(serverId);
|
Guild guildById = bot.getGuildById(serverId);
|
||||||
if(guildById != null) {
|
AEmote emote = emoteManagementService.loadEmoteByName(emoteKey, serverId);
|
||||||
AEmote emote = emoteManagementService.loadEmoteByName(emoteKey, serverId);
|
if(emote.getCustom()) {
|
||||||
if(emote.getCustom()) {
|
Emote emoteById = guildById.getEmoteById(emote.getEmoteId());
|
||||||
Emote emoteById = guildById.getEmoteById(emote.getEmoteId());
|
if(emoteById != null) {
|
||||||
if(emoteById != null) {
|
message.addReaction(emoteById).queue();
|
||||||
message.addReaction(emoteById).queue();
|
|
||||||
} else {
|
|
||||||
log.warn("Emote with key {} and id {} for guild {} was not found.", emoteKey, emote.getEmoteId(), guildById.getId());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
message.addReaction(emote.getEmoteKey()).queue();
|
log.warn("Emote with key {} and id {} for guild {} was not found.", emoteKey, emote.getEmoteId(), guildById.getId());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.warn("Guild {} was not found when trying to react to a message.", serverId);
|
message.addReaction(emote.getEmoteKey()).queue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
package dev.sheldan.abstracto.listener;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.management.ChannelManagementService;
|
||||||
|
import dev.sheldan.abstracto.core.management.ServerManagementService;
|
||||||
|
import dev.sheldan.abstracto.core.management.UserManagementService;
|
||||||
|
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||||
|
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 dev.sheldan.abstracto.core.models.listener.MessageEmbeddedModel;
|
||||||
|
import dev.sheldan.abstracto.core.service.Bot;
|
||||||
|
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||||
|
import dev.sheldan.abstracto.templating.TemplateService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
|
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
|
||||||
|
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class MessageEmbedListener extends ListenerAdapter {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MessageCache messageCache;
|
||||||
|
|
||||||
|
public static final String MESSAGE_EMBED_TEMPLATE = "message";
|
||||||
|
|
||||||
|
private Pattern messageRegex = Pattern.compile("(?<whole>https://discordapp.com/channels/(?<server>\\d+)/(?<channel>\\d+)/(?<message>\\d+)(?:.*?))+");
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MessageEmbedListener self;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ChannelManagementService channelManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ServerManagementService serverManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserManagementService userManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Bot bot;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TemplateService templateService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void onGuildMessageReceived(@Nonnull GuildMessageReceivedEvent event) {
|
||||||
|
String messageRaw = event.getMessage().getContentRaw();
|
||||||
|
Matcher matcher = messageRegex.matcher(messageRaw);
|
||||||
|
boolean matched = false;
|
||||||
|
while(matcher.find()) {
|
||||||
|
matched = true;
|
||||||
|
String serverId = matcher.group("server");
|
||||||
|
String channelId = matcher.group("channel");
|
||||||
|
String messageId = matcher.group("message");
|
||||||
|
String wholeLink = matcher.group("whole");
|
||||||
|
if(event.getMessage().getGuild().getId().equals(serverId)) {
|
||||||
|
Long serverIdLong = Long.parseLong(serverId);
|
||||||
|
Long channelIdLong = Long.parseLong(channelId);
|
||||||
|
Long messageIdLong = Long.parseLong(messageId);
|
||||||
|
try {
|
||||||
|
CachedMessage messageFromCache = messageCache.getMessageFromCache(serverIdLong, channelIdLong, messageIdLong);
|
||||||
|
messageRaw = messageRaw.replace(wholeLink, "");
|
||||||
|
self.createEmbedAndPostEmbed(event, messageFromCache);
|
||||||
|
} catch (ExecutionException | InterruptedException e) {
|
||||||
|
log.warn("Failed to load message from cache", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(StringUtils.isBlank(messageRaw) && matched) {
|
||||||
|
event.getMessage().delete().queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||||
|
public void createEmbedAndPostEmbed(@Nonnull GuildMessageReceivedEvent event, CachedMessage message) {
|
||||||
|
MessageEmbeddedModel messageEmbeddedModel = buildTemplateParameter(event, message);
|
||||||
|
MessageEmbed embed = templateService.renderEmbedTemplate(MESSAGE_EMBED_TEMPLATE, messageEmbeddedModel);
|
||||||
|
event.getChannel().sendMessage(embed).queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessageEmbeddedModel buildTemplateParameter(GuildMessageReceivedEvent event, CachedMessage embeddedMessage) {
|
||||||
|
AChannel channel = channelManagementService.loadChannel(event.getChannel().getIdLong());
|
||||||
|
AServer server = serverManagementService.loadServer(event.getGuild().getIdLong());
|
||||||
|
AUserInAServer user = userManagementService.loadUser(event.getMember());
|
||||||
|
Member author = bot.getMemberInServer(embeddedMessage.getServerId(), embeddedMessage.getAuthorId());
|
||||||
|
return MessageEmbeddedModel
|
||||||
|
.builder()
|
||||||
|
.channel(channel)
|
||||||
|
.server(server)
|
||||||
|
.member(event.getMember())
|
||||||
|
.aUserInAServer(user)
|
||||||
|
.author(author)
|
||||||
|
.sourceChannel(event.getChannel())
|
||||||
|
.embeddingUser(event.getMember())
|
||||||
|
.user(user.getUserReference())
|
||||||
|
.textChannel(event.getChannel())
|
||||||
|
.guild(event.getGuild())
|
||||||
|
.embeddedMessage(embeddedMessage)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
package dev.sheldan.abstracto.listener;
|
package dev.sheldan.abstracto.listener;
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.MessageTextUpdatedListener;
|
import dev.sheldan.abstracto.core.MessageTextUpdatedListener;
|
||||||
|
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageUpdateEvent;
|
import net.dv8tion.jda.api.events.message.guild.GuildMessageUpdateEvent;
|
||||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||||
@@ -10,8 +12,10 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@Slf4j
|
||||||
public class MessageUpdatedListener extends ListenerAdapter {
|
public class MessageUpdatedListener extends ListenerAdapter {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -22,10 +26,15 @@ public class MessageUpdatedListener extends ListenerAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGuildMessageUpdate(@Nonnull GuildMessageUpdateEvent event) {
|
public void onGuildMessageUpdate(@Nonnull GuildMessageUpdateEvent event) {
|
||||||
Message fromCache = messageCache.getMessageFromCache(event.getMessage());
|
Message message = event.getMessage();
|
||||||
listener.forEach(messageTextUpdatedListener -> {
|
try {
|
||||||
messageTextUpdatedListener.execute(fromCache, event.getMessage());
|
CachedMessage fromCache = messageCache.getMessageFromCache(message.getGuild().getIdLong(), message.getTextChannel().getIdLong(), event.getMessageIdLong());
|
||||||
});
|
listener.forEach(messageTextUpdatedListener -> {
|
||||||
messageCache.putMessageInCache(event.getMessage());
|
messageTextUpdatedListener.execute(fromCache, message);
|
||||||
|
});
|
||||||
|
messageCache.putMessageInCache(message);
|
||||||
|
} catch (ExecutionException | InterruptedException e) {
|
||||||
|
log.warn("Failed to load message", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"author": {
|
||||||
|
"name": "${author.effectiveName}",
|
||||||
|
"avatar": "${author.user.avatarUrl}"
|
||||||
|
},
|
||||||
|
"color" : {
|
||||||
|
"r": 200,
|
||||||
|
"g": 0,
|
||||||
|
"b": 255
|
||||||
|
},
|
||||||
|
<#if embeddedMessage.content?has_content >
|
||||||
|
"description": "${embeddedMessage.content}",
|
||||||
|
</#if>
|
||||||
|
<#if embeddedMessage.attachmentUrls?size gt 0>
|
||||||
|
"imageUrl": "${embeddedMessage.attachmentUrls[0]}",
|
||||||
|
</#if>
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "Quoted by",
|
||||||
|
"value": "${embeddingUser.asMention} from [${sourceChannel.name}](${embeddedMessage.messageUrl})"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timeStamp": "${embeddedMessage.timeCreated}"
|
||||||
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package dev.sheldan.abstracto.core;
|
package dev.sheldan.abstracto.core;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
|
||||||
public interface MessageTextUpdatedListener {
|
public interface MessageTextUpdatedListener {
|
||||||
void execute(Message messageBefore, Message messageAfter);
|
void execute(CachedMessage messageBefore, Message messageAfter);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package dev.sheldan.abstracto.core.models;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.embed.CachedEmbed;
|
||||||
|
import dev.sheldan.abstracto.core.utils.MessageUtils;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
public class CachedMessage {
|
||||||
|
private Long serverId;
|
||||||
|
private Long channelId;
|
||||||
|
private Long messageId;
|
||||||
|
private Long authorId;
|
||||||
|
private OffsetDateTime timeCreated;
|
||||||
|
private String content;
|
||||||
|
private List<CachedEmbed> embeds;
|
||||||
|
private List<String> attachmentUrls;
|
||||||
|
|
||||||
|
public String getMessageUrl() {
|
||||||
|
return MessageUtils.buildMessageUrl(this.serverId ,this.channelId, this.messageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package dev.sheldan.abstracto.core.models;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.TextChannel;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
public class ServerChannelUser {
|
||||||
|
public Guild guild;
|
||||||
|
private TextChannel textChannel;
|
||||||
|
private Member member;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package dev.sheldan.abstracto.core.models.embed;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
public class CachedEmbed {
|
||||||
|
private EmbedAuthor author;
|
||||||
|
private EmbedTitle title;
|
||||||
|
private EmbedColor color;
|
||||||
|
private String description;
|
||||||
|
private String thumbnail;
|
||||||
|
private String imageUrl;
|
||||||
|
private List<EmbedField> fields;
|
||||||
|
private EmbedFooter footer;
|
||||||
|
private OffsetDateTime timeStamp;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package dev.sheldan.abstracto.core.models.embed;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
public class EmbedAuthor {
|
||||||
|
private String name;
|
||||||
|
private String url;
|
||||||
|
private String avatar;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package dev.sheldan.abstracto.core.models.embed;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
public class EmbedColor {
|
||||||
|
private Integer r;
|
||||||
|
private Integer g;
|
||||||
|
private Integer b;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package dev.sheldan.abstracto.core.models.embed;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
public class EmbedConfiguration {
|
||||||
|
private EmbedAuthor author;
|
||||||
|
private EmbedTitle title;
|
||||||
|
private EmbedColor color;
|
||||||
|
private String description;
|
||||||
|
private String thumbnail;
|
||||||
|
private String imageUrl;
|
||||||
|
private List<EmbedField> fields;
|
||||||
|
private EmbedFooter footer;
|
||||||
|
private OffsetDateTime timeStamp;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package dev.sheldan.abstracto.core.models.embed;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
public class EmbedField {
|
||||||
|
private String name;
|
||||||
|
private String value;
|
||||||
|
private Boolean inline;
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package dev.sheldan.abstracto.core.models.embed;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
public class EmbedFooter {
|
||||||
|
private String text;
|
||||||
|
private String icon;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package dev.sheldan.abstracto.core.models.embed;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
public class EmbedTitle {
|
||||||
|
private String title;
|
||||||
|
private String url;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package dev.sheldan.abstracto.core.models.listener;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||||
|
import dev.sheldan.abstracto.core.models.UserInitiatedServerContext;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.TextChannel;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@SuperBuilder
|
||||||
|
public class MessageEmbeddedModel extends UserInitiatedServerContext {
|
||||||
|
private CachedMessage embeddedMessage;
|
||||||
|
private TextChannel sourceChannel;
|
||||||
|
private Member author;
|
||||||
|
private Member embeddingUser;
|
||||||
|
}
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
package dev.sheldan.abstracto.core.service;
|
package dev.sheldan.abstracto.core.service;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.ServerChannelUser;
|
||||||
import net.dv8tion.jda.api.JDA;
|
import net.dv8tion.jda.api.JDA;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.TextChannel;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
@@ -9,5 +13,9 @@ import javax.security.auth.login.LoginException;
|
|||||||
public interface Bot {
|
public interface Bot {
|
||||||
void login() throws LoginException;
|
void login() throws LoginException;
|
||||||
JDA getInstance();
|
JDA getInstance();
|
||||||
|
ServerChannelUser getServerChannelUser(Long serverId, Long channelId, Long userId);
|
||||||
|
Member getMemberInServer(Long serverId, Long memberId);
|
||||||
|
TextChannel getTextChannelFromServer(Long serverId, Long textChannelId);
|
||||||
|
Guild getGuildById(Long serverId);
|
||||||
void shutdown();
|
void shutdown();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package dev.sheldan.abstracto.core.service;
|
package dev.sheldan.abstracto.core.service;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
public interface MessageCache {
|
public interface MessageCache {
|
||||||
Message putMessageInCache(Message message);
|
CachedMessage putMessageInCache(Message message);
|
||||||
Message getMessageFromCache(Message message);
|
CachedMessage getMessageFromCache(Message message) throws ExecutionException, InterruptedException;
|
||||||
Message getMessageFromCache(Long messageId, Long textChannelId, Long guildId);
|
CachedMessage getMessageFromCache(Long guildId, Long textChannelId, Long messageId) throws ExecutionException, InterruptedException;
|
||||||
|
CompletableFuture<Message> getMessage(Long serverId, Long textChannelId, Long messageId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ package dev.sheldan.abstracto.core.utils;
|
|||||||
import dev.sheldan.abstracto.core.management.ChannelManagementService;
|
import dev.sheldan.abstracto.core.management.ChannelManagementService;
|
||||||
import dev.sheldan.abstracto.core.management.ServerManagementService;
|
import dev.sheldan.abstracto.core.management.ServerManagementService;
|
||||||
import dev.sheldan.abstracto.core.management.UserManagementService;
|
import dev.sheldan.abstracto.core.management.UserManagementService;
|
||||||
|
import dev.sheldan.abstracto.core.models.CachedMessage;
|
||||||
|
import dev.sheldan.abstracto.core.models.ServerChannelUser;
|
||||||
import dev.sheldan.abstracto.core.models.UserInitiatedServerContext;
|
import dev.sheldan.abstracto.core.models.UserInitiatedServerContext;
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
|
import dev.sheldan.abstracto.core.service.Bot;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
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.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -26,18 +28,22 @@ public class ContextUtils {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ServerManagementService serverManagementService;
|
private ServerManagementService serverManagementService;
|
||||||
|
|
||||||
public <T extends UserInitiatedServerContext> UserInitiatedServerContext fromMessage(Message message, Class<T> clazz) {
|
@Autowired
|
||||||
|
private Bot bot;
|
||||||
|
|
||||||
|
public <T extends UserInitiatedServerContext> UserInitiatedServerContext fromMessage(CachedMessage message, Class<T> clazz) {
|
||||||
Method m = null;
|
Method m = null;
|
||||||
|
ServerChannelUser serverChannelUser = bot.getServerChannelUser(message.getServerId(), message.getChannelId(), message.getAuthorId());
|
||||||
try {
|
try {
|
||||||
m = clazz.getMethod("builder");
|
m = clazz.getMethod("builder");
|
||||||
UserInitiatedServerContext.UserInitiatedServerContextBuilder<?, ?> builder = (UserInitiatedServerContext.UserInitiatedServerContextBuilder) m.invoke(null, null);
|
UserInitiatedServerContext.UserInitiatedServerContextBuilder<?, ?> builder = (UserInitiatedServerContext.UserInitiatedServerContextBuilder) m.invoke(null, null);
|
||||||
AUserInAServer aUserInAServer = userManagementService.loadUser(message.getMember());
|
AUserInAServer aUserInAServer = userManagementService.loadUser(message.getServerId(), message.getAuthorId());
|
||||||
return builder
|
return builder
|
||||||
.member(message.getMember())
|
.member(serverChannelUser.getMember())
|
||||||
.guild(message.getGuild())
|
.guild(serverChannelUser.getGuild())
|
||||||
.textChannel(message.getTextChannel())
|
.textChannel(serverChannelUser.getTextChannel())
|
||||||
.channel(channelManagementService.loadChannel(message.getTextChannel().getIdLong()))
|
.channel(channelManagementService.loadChannel(message.getChannelId()))
|
||||||
.server(serverManagementService.loadServer(message.getGuild().getIdLong()))
|
.server(serverManagementService.loadServer(message.getServerId()))
|
||||||
.aUserInAServer(aUserInAServer)
|
.aUserInAServer(aUserInAServer)
|
||||||
.user(aUserInAServer.getUserReference())
|
.user(aUserInAServer.getUserReference())
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package dev.sheldan.abstracto.templating.embed;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Getter @Setter
|
@Getter @Setter
|
||||||
@@ -15,4 +16,5 @@ public class EmbedConfiguration {
|
|||||||
private String imageUrl;
|
private String imageUrl;
|
||||||
private List<EmbedField> fields;
|
private List<EmbedField> fields;
|
||||||
private EmbedFooter footer;
|
private EmbedFooter footer;
|
||||||
|
private OffsetDateTime timeStamp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ public class TemplateServiceBean implements TemplateService {
|
|||||||
builder.addField(embedField.getName(), embedField.getValue(), inline);
|
builder.addField(embedField.getName(), embedField.getValue(), inline);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
builder.setTimestamp(configuration.getTimeStamp());
|
||||||
|
|
||||||
builder.setImage(configuration.getImageUrl());
|
builder.setImage(configuration.getImageUrl());
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package dev.sheldan.abstracto.templating.embed;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class EmbedAuthor {
|
||||||
|
private String name;
|
||||||
|
private String url;
|
||||||
|
private String avatar;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package dev.sheldan.abstracto.templating.embed;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class EmbedColor {
|
||||||
|
private Integer r;
|
||||||
|
private Integer g;
|
||||||
|
private Integer b;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package dev.sheldan.abstracto.templating.embed;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class EmbedConfiguration {
|
||||||
|
private EmbedAuthor author;
|
||||||
|
private EmbedTitle title;
|
||||||
|
private EmbedColor color;
|
||||||
|
private String description;
|
||||||
|
private String thumbnail;
|
||||||
|
private String imageUrl;
|
||||||
|
private List<EmbedField> fields;
|
||||||
|
private EmbedFooter footer;
|
||||||
|
private OffsetDateTime timeStamp;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package dev.sheldan.abstracto.templating.embed;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class EmbedField {
|
||||||
|
private String name;
|
||||||
|
private String value;
|
||||||
|
private Boolean inline;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package dev.sheldan.abstracto.templating.embed;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class EmbedFooter {
|
||||||
|
private String text;
|
||||||
|
private String icon;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package dev.sheldan.abstracto.templating.embed;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class EmbedTitle {
|
||||||
|
private String title;
|
||||||
|
private String url;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user