sxcybot

OSRS oriented Discord Bot
git clone git://git.wimdupont.com/sxcybot.git
Log | Files | Refs | README | LICENSE

ChatModService.java (4827B)


      1 package com.wimdupont.sxcybot.services.guild;
      2 
      3 import com.wimdupont.sxcybot.repository.guild.ChatDataRepository;
      4 import com.wimdupont.sxcybot.repository.guild.dao.ChatData;
      5 import net.dv8tion.jda.api.entities.Guild;
      6 import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
      7 import net.dv8tion.jda.api.exceptions.ErrorResponseException;
      8 import net.dv8tion.jda.api.exceptions.HierarchyException;
      9 import net.dv8tion.jda.api.exceptions.RateLimitedException;
     10 import org.slf4j.Logger;
     11 import org.slf4j.LoggerFactory;
     12 import org.springframework.stereotype.Service;
     13 import org.springframework.transaction.annotation.Transactional;
     14 import org.springframework.util.StringUtils;
     15 
     16 import java.time.LocalDateTime;
     17 import java.util.List;
     18 
     19 @Service
     20 @Transactional
     21 public class ChatModService {
     22 
     23     private static final Logger LOGGER = LoggerFactory.getLogger(ChatModService.class);
     24     private final ChatDataRepository chatDataRepository;
     25 
     26     public ChatModService(ChatDataRepository chatDataRepository) {
     27         this.chatDataRepository = chatDataRepository;
     28     }
     29 
     30     public boolean isAllowed(MessageReceivedEvent event) {
     31         if (event.getMember() == null || event.getMember().getUser().isBot() || !containsUrl(event))
     32             return true;
     33 
     34         var discordId = event.getMember().getUser().getId();
     35         var previousUrlMessages = chatDataRepository.findAllByDiscordIdAndWithUrlTrueOrderByCreatedDateTimeDesc(discordId);
     36         var currentData = persist(discordId, event.getChannel().asTextChannel().getId(), event.getMessageId());
     37 
     38         return isValidForHistory(previousUrlMessages, event, currentData);
     39     }
     40 
     41     private boolean isValidForHistory(List<ChatData> previousUrlMessages,
     42                                       MessageReceivedEvent event,
     43                                       ChatData currentData) {
     44         if (previousUrlMessages.isEmpty())
     45             return true;
     46         try {
     47             LocalDateTime latest = previousUrlMessages.stream().findFirst()
     48                     .map(ChatData::getCreatedDateTime)
     49                     .orElseThrow();
     50             if (latest.plusMinutes(1L).isBefore(LocalDateTime.now())) {
     51                 chatDataRepository.deleteAll(previousUrlMessages);
     52             } else if (previousUrlMessages.size() >= 2 && previousUrlMessages.size() < 4) {
     53                 dmWarning(event);
     54             } else if (previousUrlMessages.size() >= 4 && event.getMember() != null) {
     55                 try {
     56                     event.getMember().kick().reason("Spamming URL's.").queue();
     57                 } catch (HierarchyException | ErrorResponseException e) {
     58                     LOGGER.error(e.getMessage(), e);
     59                 }
     60                 for (ChatData chatData : previousUrlMessages) {
     61                     removeMessage(event.getGuild(), chatData);
     62                 }
     63                 removeMessage(event.getGuild(), currentData);
     64                 return false;
     65             }
     66         } catch (RateLimitedException | ErrorResponseException e) {
     67             LOGGER.error(e.getMessage(), e);
     68         }
     69         return true;
     70     }
     71 
     72     private ChatData persist(String discordId, String channelId, String messageId) {
     73         return chatDataRepository.save(ChatData.Builder.newBuilder()
     74                 .discordId(discordId)
     75                 .channelId(channelId)
     76                 .messageId(messageId)
     77                 .withUrl(true)
     78                 .build());
     79     }
     80 
     81     private void dmWarning(MessageReceivedEvent event) throws RateLimitedException {
     82         if (event.getMember() != null) {
     83             var privateChannel = event.getMember().getUser().openPrivateChannel().complete(true);
     84             privateChannel.sendMessage(String.format("Warning: stop spamming URL's! (server: %s)",
     85                     event.getGuild().getName())).queue();
     86         }
     87     }
     88 
     89     private void removeMessage(Guild guild, ChatData chatData) throws RateLimitedException {
     90         var channel = guild.getTextChannelById(chatData.getChannelId());
     91         if (channel != null) {
     92             channel.retrieveMessageById(chatData.getMessageId()).complete(true).delete().queue();
     93             chatDataRepository.delete(chatData);
     94         }
     95     }
     96 
     97     private boolean containsUrl(MessageReceivedEvent event) {
     98         var msg = event.getMessage().getContentRaw().toLowerCase();
     99         if (containsUrl(msg))
    100             return true;
    101 
    102         if (!event.getMessage().getEmbeds().isEmpty()) {
    103             return event.getMessage().getEmbeds().stream()
    104                     .anyMatch(f -> StringUtils.hasLength(f.getUrl())
    105                             || containsUrl(f.getTitle())
    106                             || containsUrl(f.getDescription()));
    107         }
    108         return false;
    109     }
    110 
    111     private boolean containsUrl(String msg) {
    112         return msg != null && msg.matches(".*https?://.*|.*www\\..*");
    113     }
    114 }