Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add twitter listener #99

Merged
merged 7 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/main/java/com/softawii/capivara/config/SpringConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
public JDA jda() {
JDA jda;
try {
JDABuilder builder = JDABuilder.create(discordToken, GatewayIntent.GUILD_MEMBERS, GatewayIntent.GUILD_VOICE_STATES, GatewayIntent.GUILD_EMOJIS_AND_STICKERS, GatewayIntent.GUILD_PRESENCES);
JDABuilder builder = JDABuilder.create(
discordToken,
GatewayIntent.GUILD_MEMBERS,
GatewayIntent.GUILD_VOICE_STATES,
GatewayIntent.GUILD_EMOJIS_AND_STICKERS,
GatewayIntent.GUILD_PRESENCES,
GatewayIntent.GUILD_MESSAGES,
GatewayIntent.MESSAGE_CONTENT);
builder.setMemberCachePolicy(MemberCachePolicy.ALL);
builder.enableCache(CacheFlag.EMOJI, CacheFlag.ROLE_TAGS, CacheFlag.MEMBER_OVERRIDES, CacheFlag.STICKER);
jda = builder.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.softawii.capivara.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class TwitterParserConfig {
@Id
@Column(unique = true, nullable = false)
private Long guildId;

public TwitterParserConfig() {
}

public TwitterParserConfig(Long guildId) {
this.guildId = guildId;
}

public Long getGuildId() {
return guildId;
}

public void setGuildId(Long guildId) {
this.guildId = guildId;
}
}
77 changes: 77 additions & 0 deletions src/main/java/com/softawii/capivara/listeners/TwitterGroup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.softawii.capivara.listeners;

import com.softawii.capivara.services.TwitterParserConfigService;
import com.softawii.curupira.annotations.IButton;
import com.softawii.curupira.annotations.ICommand;
import com.softawii.curupira.annotations.IGroup;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.channel.unions.MessageChannelUnion;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@IGroup(name = "twitter", description = "Transformação de links do Twitter automática", hidden = false)
@Component
public class TwitterGroup {

public static final String deleteBotTwitterMessage = "twitter-bot-message-delete";
private static TwitterParserConfigService service;

@Autowired
@SuppressWarnings("unused")
public void setCurupira(TwitterParserConfigService service) {
TwitterGroup.service = service;
}

@ICommand(name = "enable", description = "Ativa o serviço de transformação de links do Twitter automática",
permissions = {Permission.ADMINISTRATOR})
@SuppressWarnings("unused")
public static void enable(SlashCommandInteractionEvent event) {
long guildId = event.getGuild().getIdLong();
if (service.isEnabled(guildId)) {
event.reply("O serviço já está ativado").setEphemeral(true).queue();
return;
}

service.enable(guildId);
event.reply("O serviço foi está ativado").setEphemeral(true).queue();
}

@ICommand(name = "disable", description = "Desativa o serviço de transformação de links do Twitter automática",
permissions = {Permission.ADMINISTRATOR})
@SuppressWarnings("unused")
public static void disable(SlashCommandInteractionEvent event) {
long guildId = event.getGuild().getIdLong();
if (!service.isEnabled(guildId)) {
event.reply("O serviço não está ativado").setEphemeral(true).queue();
return;
}

service.disable(guildId);
event.reply("O serviço foi está ativado").setEphemeral(true).queue();
}

@IButton(id = deleteBotTwitterMessage)
@SuppressWarnings("unused")
public static void delete(ButtonInteractionEvent event) {
// Format: ButtonID:Owner
String ownerId = event.getComponentId().split(":")[1];
String messageOwner = event.getMember().getId();

MessageChannelUnion channel = event.getChannel();

if (!messageOwner.equals(ownerId)) {
event.reply("Você não pode apagar essa mensagem").setEphemeral(true).queue();
return;
}

event.reply("Mensagem apagada").setEphemeral(true).queue();
channel.deleteMessageById(event.getMessageId()).queue();
}

public static Button generateDeleteButton(long authorId) {
return Button.danger(String.format("%s:%s", deleteBotTwitterMessage, authorId), "Apagar");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.softawii.capivara.listeners.events;

import com.softawii.capivara.listeners.TwitterGroup;
import com.softawii.capivara.services.TwitterParserConfigService;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.unions.MessageChannelUnion;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.events.message.MessageUpdateEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.requests.RestAction;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;

import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
@SuppressWarnings("unused")
public class TwitterListener extends ListenerAdapter {
private final Pattern twitterPattern;
private final TwitterParserConfigService service;

public TwitterListener(JDA jda, TwitterParserConfigService service) {
this.service = service;
this.twitterPattern = Pattern.compile("^https://(twitter|x)\\.com/(?<username>\\w+)/status/(?<postId>\\d+)([-a-zA-Z0-9()@:%_+.~#?&/=]*)$"); // https://stackoverflow.com/a/17773849
jda.addEventListener(this);
}

@Override
public void onMessageReceived(@NotNull MessageReceivedEvent event) {
if (event.getAuthor().isBot()) return;

String rawMessage = event.getMessage().getContentRaw();
User author = event.getAuthor();
Optional<String> parsedMessage = parseMessage(rawMessage, author);

parsedMessage.ifPresent(message -> createTweetMessage(event.getGuild().getIdLong(), message, event.getMessage()));
}

@Override
public void onMessageUpdate(@NotNull MessageUpdateEvent event) {
if (event.getAuthor().isBot()) return;

String rawMessage = event.getMessage().getContentRaw();
User author = event.getAuthor();
Optional<String> parsedMessage = parseMessage(rawMessage, author);

parsedMessage.ifPresent(message -> createTweetMessage(event.getGuild().getIdLong(), message, event.getMessage()));
}

private void createTweetMessage(Long guildId, String replacementMessage, Message originalMessage) {
if (!service.isEnabled(guildId)) return;

MessageChannelUnion channel = originalMessage.getChannel();

RestAction.allOf(
originalMessage.delete(),
channel.sendMessage(replacementMessage)
.addActionRow(TwitterGroup.generateDeleteButton(originalMessage.getAuthor().getIdLong()))
.setSuppressedNotifications(true)
).queue();
}

private Optional<String> parseMessage(String twitterLink, User author) {
Matcher matcher = this.twitterPattern.matcher(twitterLink);

if (matcher.find()) {
String twitterUsername = matcher.group("username");
String twitterPostId = matcher.group("postId");

String result = String.format(
"""
Autor: %s
Link original: `%s`
[Postagem](https://fxtwitter.com/%s/status/%s)
""", author.getAsMention(), twitterLink, twitterUsername, twitterPostId);
return Optional.of(result);
}

return Optional.empty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.softawii.capivara.repository;

import com.softawii.capivara.entity.TwitterParserConfig;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface TwitterParserConfigRepository extends JpaRepository<TwitterParserConfig, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.softawii.capivara.services;

import com.softawii.capivara.entity.TwitterParserConfig;
import com.softawii.capivara.repository.TwitterParserConfigRepository;
import org.springframework.stereotype.Service;

@Service
public class TwitterParserConfigService {

private final TwitterParserConfigRepository repository;

public TwitterParserConfigService(TwitterParserConfigRepository repository) {
this.repository = repository;
}

public boolean isEnabled(Long guildId) {
return repository.existsById(guildId);
}

public void enable(Long guildId) {
repository.save(new TwitterParserConfig(guildId));
}

public void disable(Long guildId) {
repository.deleteById(guildId);
}
}
Loading