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

Perguntas Anónimas #62

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
47 changes: 47 additions & 0 deletions application/usecases/readDirectMessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Message, Client, MessageEmbed, MessageActionRow, MessageButton } from "discord.js";
import sendDM from "./sendMessageToChannel/sendDM";
import PerguntaChatService from "./sendMessageToChannel/sendPerguntaToChannel";
import DiscordEmbedService from "../../infrastructure/service/discordEmbedService";

class DirectMessage {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Por norma temos declarado as classes com o mesmo nome do ficheiro e com o sufixo UseCase. Consegues alterar?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feito

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feito

constructor(private message: Message, private client: Client) {}

async validate() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tendo em conta que a função validate retorna um bool e não um void, sugiro um isValid, penso fazer mais sentido.

E assim o teu if poderia ser um if (await isValid()) {.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feito

if (this.message.author.id === this.client.user?.id) {
return false;
}

if (
this.message.channel.type === "DM" &&
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think there should be a ENUM here for types

this.message.content.startsWith("!pergunta") &&
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

☝️

this.message.content.split(" ").length > 1 &&
this.message.content.length <= 1500
) {
return true;
}
sendDM(this.client, this.message.author.id, "Por favor usa o seguinte formato:\n!pergunta <mensagem>");
return false;
}

async messageApprove() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trocaria talvez o verbo para ficar em primeiro? Isto porque lemos "aprovar mensagem" e não "mensagem aprovar" 😅 que achas?

Suggested change
async messageApprove() {
async approveMessage(): void {

const canalPerguntaAnonima = this.client.channels.cache.get("1066328934825865216");
const chatService: PerguntaChatService = new DiscordEmbedService(this.client);
const modChannel = "987719981443723266";
zorkpt marked this conversation as resolved.
Show resolved Hide resolved
const sentence = this.message.content.split(" ").slice(1).join(" ");
const row = new MessageActionRow().addComponents(
new MessageButton().setLabel("Aprovar").setStyle("SUCCESS").setCustomId("bt1"),
new MessageButton().setCustomId("bt2").setLabel("Eliminar").setStyle("DANGER")
zorkpt marked this conversation as resolved.
Show resolved Hide resolved
);
const Mensagem = new MessageEmbed().setColor("#0099ff").setTitle("Pergunta Anónima").setDescription(sentence);
zorkpt marked this conversation as resolved.
Show resolved Hide resolved

await chatService.sendEmbedToChannel(Mensagem, row, modChannel);
const dmSent = sendDM(
this.client,
this.message.author.id,
`A tua pergunta foi colocada com sucesso.\nApós aprovação poderás visualizar no ${canalPerguntaAnonima} `
);
if (!dmSent) console.log("dm não enviada");
}
}

export default DirectMessage;
18 changes: 18 additions & 0 deletions application/usecases/sendMessageToChannel/sendDM.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Client } from "discord.js";

function sendMessage(client: Client, userId: string, message: string): boolean {
client.users
.fetch(userId)
.then(async (user) => {
const exists = await user.send(message);
const res = !!exists;
return res;
})
.catch((e) => {
console.log(e);
return false;
});
return false;
}
zorkpt marked this conversation as resolved.
Show resolved Hide resolved

export default sendMessage;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { MessageEmbed, MessageActionRow } from "discord.js";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Está a importar coisas específicas do Discord.js. Aqui deveria estar a importar alguma abstração. Podemos discutir isto com o @Adjilino que ele tem lá uns pontos semelhantes também no MR dele.


export default interface SendMessageToChannel {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

O nome do ficheiro está diferente do nome da classe e presumo que o queiras deixar todo em inglês?

sendEmbedToChannel(message: MessageEmbed, row: MessageActionRow, channelId: string): void;
}
1 change: 1 addition & 0 deletions domain/service/channelResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ChannelSlug } from "../../types";
const fallbackChannelIds: Record<ChannelSlug, string> = {
[ChannelSlug.ENTRANCE]: "855861944930402344",
[ChannelSlug.JOBS]: "876826576749215744",
[ChannelSlug.QUESTION]: "876826576749215744",
};

export default class ChannelResolver {
Expand Down
1 change: 1 addition & 0 deletions domain/service/chatService.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export default interface ChatService {
sendMessageToChannel(message: string, channelId: string): void;
deleteMessageFromChannel(messageId: string, channelId: string): void;
}
59 changes: 57 additions & 2 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GuildMember, Message, Client, Intents } from "discord.js";
import { GuildMember, Message, Client, Intents, MessageEmbed } from "discord.js";
import * as dotenv from "dotenv";
import SendWelcomeMessageUseCase from "./application/usecases/sendWelcomeMessageUseCase";
import FileMessageRepository from "./infrastructure/repository/fileMessageRepository";
Expand All @@ -11,15 +11,24 @@ import CommandUseCaseResolver from "./domain/service/commandUseCaseResolver";
import ChannelResolver from "./domain/service/channelResolver";
import KataService from "./domain/service/kataService/kataService";
import CodewarsKataService from "./infrastructure/service/codewarsKataService";
import DirectMessage from "./application/usecases/readDirectMessage";

dotenv.config();

const { DISCORD_TOKEN } = process.env;

const client = new Client({
intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MEMBERS, Intents.FLAGS.GUILD_MESSAGES],
partials: ["CHANNEL"],
intents: [
Intents.FLAGS.GUILDS,
Intents.FLAGS.DIRECT_MESSAGES,
Intents.FLAGS.DIRECT_MESSAGE_TYPING,
Intents.FLAGS.GUILD_MEMBERS,
Intents.FLAGS.GUILD_MESSAGES,
],
});

const canalPerguntaAnonima = "1066328934825865216";
zorkpt marked this conversation as resolved.
Show resolved Hide resolved
const messageRepository: MessageRepository = new FileMessageRepository();
const chatService: ChatService = new DiscordChatService(client);
const loggerService: LoggerService = new ConsoleLoggerService();
Expand Down Expand Up @@ -61,3 +70,49 @@ client.on("messageCreate", (messages: Message) => {
loggerService.log(error);
}
});

client.on("message", async (message) => {
const directMessage = new DirectMessage(message, client);
const validationCheck = await directMessage.validate();
if (validationCheck) {
directMessage.messageApprove();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Como referi num comment acima, se mudarmos o naming da função podemos inclusive melhorar a legibilidade deste check e até usar early returns para a validação. (se quisermos até podemos dar logo embed do await no if.

Suggested change
const validationCheck = await directMessage.validate();
if (validationCheck) {
directMessage.messageApprove();
}
const isValid = await directMessage.isValid();
if (isValid) {
return;
}
directMessage.messageApprove();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feito

});

client.on("interactionCreate", async (interaction) => {
if (!interaction.isButton()) return;

const {
message: {
id: messageId,
embeds: [{ description: messageContent }],
},
channelId,
} = interaction;

const userName = interaction.member?.user.username;

if (!messageContent) return;
const messageApprovedEmbed = new MessageEmbed()
.setColor("#0099ff")
.setTitle("Pergunta Anónima")
.setDescription(messageContent)
.setFooter({ text: `Aprovado por ${userName}` });

switch (interaction.customId) {
case "bt1":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Este Ids deveriam ser algo mais específico caso queiramos vir a adicionar novos botões mais tarde.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feito

{
const sentence = `PERGUNTA ANÓNIMA:\n${messageContent}`;
chatService.sendMessageToChannel(sentence, canalPerguntaAnonima);
interaction.update({ components: [], embeds: [messageApprovedEmbed] });
}
break;

case "bt2":
chatService.deleteMessageFromChannel(messageId, channelId);
break;
default: {
console.log("default");
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presumo que possamos retirar isto daqui?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

não retirei porque senão não passa no lint, dá para desativar esse check ?

}
});
15 changes: 14 additions & 1 deletion infrastructure/service/discordChatService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,20 @@ export default class DiscordChatService implements ChatService {
if (!channel.isText()) {
throw new Error(`Channel with id ${channelId} is not a text channel!`);
}

channel.send(message);
}

async deleteMessageFromChannel(messageId: string, channelId: string): Promise<void> {
const channel = await this.client.channels.fetch(channelId);

if (channel === null) {
throw new Error(`Channel with id ${channelId} not found!`);
}

if (!channel.isText()) {
throw new Error(`Channel with id ${channelId} is not a text channel!`);
}

channel.messages.delete(messageId);
}
}
19 changes: 19 additions & 0 deletions infrastructure/service/discordEmbedService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Client, MessageEmbed, MessageActionRow } from "discord.js";

export default class DiscordEmbedService {
constructor(private client: Client) {}

async sendEmbedToChannel(embed: MessageEmbed, row: MessageActionRow, channelId: string): Promise<void> {
const channel = await this.client.channels.fetch(channelId);

if (channel === null) {
throw new Error(`Channel with id ${channelId} not found!`);
}

if (!channel.isText()) {
throw new Error(`Channel with id ${channelId} is not a text channel!`);
}

channel.send({ embeds: [embed], components: [row] });
}
}
Loading