Skip to content

Commit 3ddd1f3

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents f20f1a4 + 147b96e commit 3ddd1f3

18 files changed

+3518
-9593
lines changed

.github/workflows/lint-and-test.yml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,21 @@ jobs:
99
runs-on: ubuntu-latest
1010
steps:
1111
- name: Checkout code
12-
uses: actions/checkout@v3
12+
uses: actions/checkout@v4
13+
14+
- name: Set up Node.js
15+
uses: actions/setup-node@v4
16+
with:
17+
node-version: "20"
18+
19+
- name: Cache npm dependencies
20+
uses: actions/cache@v4
1321
with:
14-
node-version: "18"
15-
cache: "npm"
22+
path: ~/.npm
23+
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
24+
restore-keys: |
25+
${{ runner.os }}-node-
26+
${{ runner.os }}-
1627
1728
- name: Install dependencies
1829
run: npm ci

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# VS Code
2+
.vscode
3+
14
# Logs
25
logs
36
*.log

.prettierrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
22
"singleQuote": false,
3-
"printWidth": 120
3+
"printWidth": 120,
4+
"trailingComma": "es5"
45
}

CONTRIBUTING.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Contribuição
2+
3+
Antes de mais, obrigado por considerares participar neste projeto.
4+
5+
Neste documento encontram-se instruções detalhadas para que possas contribuir em conformidade com a estrutura e organização do projecto. Estas instruções não são para ser consideradas regras rígidas mas sim uma orientação generalizada do que esperamos quando alguém contribui, utiliza o bom senso quando estiveres a contribuir para o projecto.
6+
7+
#### Tabela de conteúdo
8+
9+
1. [Código de conduta](#código-de-conduta)
10+
2. [Arquitetura](#arquitetura)
11+
3. [Linguagem e versões](#linguagem-e-versões)
12+
4. [Como contribuir](#como-contribuir)
13+
5. [Guia de estilos](#guia-de-estilos)
14+
- [Código](#código)
15+
- [Issues](#issues)
16+
- [Mensagens de commit](#mensagens-de-commit)
17+
18+
## Código de conduta
19+
20+
Ao participares neste projeto, esperamos que tenhas em consideração as seguintes regras:
21+
22+
- Respeito pelo próximo
23+
- Uso de linguagem inclusiva e acolhedora
24+
- Aceitação de crítica construtiva
25+
- Foco no que é melhor para a comunidade
26+
27+
## Arquitetura
28+
29+
- Este projeto segue, na sua grande maioria, o estilo de _Domain-Driven Design_ (DDD). Para mais informação consulta o nosso documento sobre [Arquitetura](ARCHITECTURE)
30+
31+
## Linguagem e versões
32+
33+
- A linguagem utilizada é Typescript, e tem Node e NPM como dependências principais. As versões necessárias podem ser consultadas no [ReadMe](README).
34+
35+
Para instalar as dependências executa o comando `npm install`.
36+
37+
## Como contribuir
38+
39+
- Encontra um issue que te sentes capaz de ajudar. Se for a primeira contribuição, issues marcados com `bom primeiro issue` são normalmente considerados bons para principiantes.
40+
- Faz `fork` deste repositório para a tua conta pessoal.
41+
- Depois podes utilizar o `git` para fazer um `clone` para a tua máquina pessoal.
42+
- Cria um novo branch `git checkout -b novo-nome-branch`.
43+
- Faz as modificações que achas necessárias.
44+
- Faz commit do teu código para a origem do teu `branch`.
45+
- Cria um `pull request` no github para que possa ser revisto pela equipa.
46+
- Se receberes comentários ajusta o teu código e faz novos commits.
47+
- Quando for aprovado, o teu código vai ser `merged` com o `branch` main.
48+
49+
## Guia de estilos
50+
51+
#### Código
52+
53+
- O código deve ser escrito seguindo o estilo já presente no repositório.
54+
55+
#### Issues
56+
57+
- **Utiliza um titulo claro e descritivo** no issue para identificar a sugestão.
58+
- **Fornece uma descrição exaustiva da melhoria sugerida** usando o máximo detalhe possível.
59+
- Se aplicável, descreve os passos para replicar o issue.
60+
61+
#### Mensagens de commit
62+
63+
- Inclui referência ao Issue em questão se aplicável.

LICENSE

Lines changed: 653 additions & 228 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Discord Bot devPT
2+
3+
![](https://avatars.githubusercontent.com/u/79173787?s=200&v=4)
4+
5+
[![language](https://img.shields.io/badge/language-TypeScript-3178C6)](https://www.typescriptlang.org/) [![node_major_version](https://img.shields.io/badge/node_major_version-18-5fa04e)](https://nodejs.org/en) [![license](https://img.shields.io/github/license/devpt-org/discord-bot)](LICENSE)
6+
7+
## Descrição
8+
9+
Projeto criado em conjunto por elementos do devPT, com o intuito de criar um bot para adicionar funcionalidades extra ao servidor.
10+
11+
O devPT é uma comunidade de língua portuguesa sem fins lucrativos para developers, disponibilizando um espaço em comum para engenheiros, estudantes e curiosos da área do desenvolvimento de software para se encontrarem e desenvolverem iniciativas Open-Source.
12+
13+
## Indice
14+
15+
- [Utilização](#utilização)
16+
- [Guia de Contribuição](#guia-de-contribuição)
17+
- [Licença](#licença)
18+
- [Contactos](#contactos)
19+
- [Agradecimentos](#agradecimentos)
20+
21+
## Utilização
22+
23+
O bot está disponível no nosso discord [devPT](https://devpt.co/discord) e apresenta as seguintes funcionalidades / comandos:
24+
25+
- `!ja` - gera uma mensagem relacionada com "não perguntes para perguntar".
26+
- `!oc` - gera uma mensagem com o aviso de que o servidor é apenas para questões relacionadas com programação.
27+
- `!cwl` - gera uma mensagem que exibe o 'leaderboard' do CodeWars.
28+
- Mensagem na entrada de novos utilizadores
29+
30+
## Guia de Contribuição
31+
32+
Para detalhes sobre o nosso código de conduta e o processo para submeter um `pull request` neste projeto, por favor consulte o nosso [Guia de Contribuição](CONTRIBUTING.md).
33+
34+
## Licença
35+
36+
Este projeto está disponível gratuitamente para uso não comercial. Para mais informação, por favor consulte a nossa [Licença](LICENSE)
37+
38+
## Contactos
39+
40+
[devPT](https://devpt.co/discord)
41+
42+
## Agradecimentos
43+
44+
<a href="https://github.com/devpt-org/discord-bot/graphs/contributors">
45+
<img src="https://contrib.rocks/image?repo=devpt-org/discord-bot" />
46+
</a>
47+
48+
[Voltar ao início](#top)
Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
import KataLeaderboardUser from "../../../domain/service/kataService/kataLeaderboardUser";
2-
import KataService from "../../../domain/service/kataService/kataService";
3-
import ChatService from "../../../domain/service/chatService";
4-
import { SendCodewarsLeaderboardToChannelInput } from "./sendCodewarsLeaderboardToChannelInput";
1+
import { SendCodewarsLeaderboardToChannelInput } from "application/usecases/sendCodewarsLeaderboardToChannel/sendCodewarsLeaderboardToChannelInput";
2+
import { Command } from "../../types";
3+
import KataService from "../../domain/service/kataService/kataService";
4+
import ChatService from "../../domain/service/chatService";
5+
import KataLeaderboardUser from "../../domain/service/kataService/kataLeaderboardUser";
6+
7+
export default class CodewarsLeaderboardCommand implements Command {
8+
readonly name = "!cwl";
59

6-
export default class SendCodewarsLeaderboardToChannelUseCase {
710
private chatService: ChatService;
811

912
private kataService: KataService;
1013

11-
constructor({ chatService, kataService }: { chatService: ChatService; kataService: KataService }) {
14+
constructor(chatService: ChatService, kataService: KataService) {
1215
this.chatService = chatService;
1316
this.kataService = kataService;
1417
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Command, Context } from "../../types";
2+
import ChatService from "../../domain/service/chatService";
3+
4+
export default class DontAskToAskCommand implements Command {
5+
readonly name = "!ja";
6+
7+
private readonly message: string =
8+
"Olá! Experimenta fazer a pergunta diretamente e contar o que já tentaste! Sabe mais aqui :point_right: https://dontasktoask.com/pt-pt/";
9+
10+
private chatService: ChatService;
11+
12+
constructor(chatService: ChatService) {
13+
this.chatService = chatService;
14+
}
15+
16+
async execute(context: Context): Promise<void> {
17+
await this.chatService.sendMessageToChannel(this.message, context.channelId);
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Command, Context } from "../../types";
2+
import ChatService from "../../domain/service/chatService";
3+
4+
export default class OnlyCodeQuestionsCommand implements Command {
5+
readonly name = "!oc";
6+
7+
private chatService: ChatService;
8+
9+
private readonly message: string =
10+
":warning: Este servidor é APENAS para questões relacionadas com programação! :warning:";
11+
12+
constructor(chatService: ChatService) {
13+
this.chatService = chatService;
14+
}
15+
16+
async execute(context: Context): Promise<void> {
17+
await this.chatService.sendMessageToChannel(this.message, context.channelId);
18+
}
19+
}

assets/phrases/welcoming.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[
2-
", o que te trás por cá?",
2+
", o que te traz por cá?",
33
", como estás?",
44
", já viste o sol hoje?",
55
", já viste a luz do dia?",
@@ -19,10 +19,10 @@
1919
". A única solução que vejo para isso é formatar...",
2020
". E quê? Já falas melhor em Python que em português?",
2121
". Então e qual a linguagem que queres aprender?",
22-
", se já viste https://youtu.be/MAlSjtxy5ak talvez aqui tenhas mais sorte!",
22+
", se já viste <https://youtu.be/MAlSjtxy5ak> talvez aqui tenhas mais sorte!",
2323
", ufa, foi por pouco que não te apanhávamos!",
2424
", já contaste ao patinho?",
25-
", https://youtu.be/a3Z7zEc7AXQ",
25+
", <https://www.youtube.com/watch?v=xvFZjo5PgG0>",
2626
". Se o Google não ajudar, força nisso!",
2727
". Se quiseres aprender a programar, podes contar com o nosso apoio!",
2828
". Acho que estás a merecer um !ja",
Lines changed: 9 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,27 @@
1-
import { Context } from "../../types";
1+
import { Command, Context } from "../../types";
22
import UseCaseNotFound from "../exception/useCaseNotFound";
3-
import SendMessageToChannelUseCase from "../../application/usecases/sendMessageToChannel/sendMessageToChannelUseCase";
4-
import MessageRepository from "../repository/messageRepository";
5-
import ChatService from "./chatService";
63
import LoggerService from "./loggerService";
7-
import ChannelResolver from "./channelResolver";
8-
import KataService from "./kataService/kataService";
9-
import SendCodewarsLeaderboardToChannelUseCase from "../../application/usecases/sendCodewarsLeaderboardToChannel/sendCodewarsLeaderboardToChannelUseCase";
10-
11-
type CallbackFunctionVariadic = (...args: unknown[]) => void;
124

135
export default class CommandUseCaseResolver {
14-
private messageRepository: MessageRepository;
15-
16-
private chatService: ChatService;
6+
private commands: Command[];
177

188
private loggerService: LoggerService;
199

20-
private channelResolver: ChannelResolver;
21-
22-
private kataService: KataService;
23-
24-
constructor({
25-
messageRepository,
26-
chatService,
27-
loggerService,
28-
channelResolver,
29-
kataService,
30-
}: {
31-
messageRepository: MessageRepository;
32-
chatService: ChatService;
33-
loggerService: LoggerService;
34-
channelResolver: ChannelResolver;
35-
kataService: KataService;
36-
}) {
37-
this.messageRepository = messageRepository;
38-
this.chatService = chatService;
10+
constructor({ commands, loggerService }: { commands: Command[]; loggerService: LoggerService }) {
3911
this.loggerService = loggerService;
40-
this.channelResolver = channelResolver;
41-
this.kataService = kataService;
12+
13+
this.commands = commands;
4214
}
4315

44-
resolveByCommand(command: string, context: Context): void {
16+
async resolveByCommand(command: string, context: Context): Promise<void> {
4517
this.loggerService.log(`Command received: "${command}"`);
4618

47-
const deps = {
48-
messageRepository: this.messageRepository,
49-
chatService: this.chatService,
50-
loggerService: this.loggerService,
51-
channelResolver: this.channelResolver,
52-
kataService: this.kataService,
53-
};
54-
55-
const commandUseCases: Record<string, CallbackFunctionVariadic> = {
56-
"!ja": async () =>
57-
new SendMessageToChannelUseCase(deps).execute({
58-
channelId: context.channelId,
59-
message:
60-
"Olá! Experimenta fazer a pergunta diretamente e contar o que já tentaste! Sabe mais aqui :point_right: https://dontasktoask.com/pt-pt/",
61-
}),
62-
"!oc": async () =>
63-
new SendMessageToChannelUseCase(deps).execute({
64-
channelId: context.channelId,
65-
message: ":warning: Este servidor é APENAS para questões relacionadas com programação! :warning:",
66-
}),
67-
"!cwl": async () =>
68-
new SendCodewarsLeaderboardToChannelUseCase(deps).execute({
69-
channelId: context.channelId,
70-
}),
71-
};
19+
const commandInstance = this.commands.find((cmd) => cmd.name === command);
7220

73-
if (!commandUseCases[command]) {
21+
if (!commandInstance) {
7422
throw new UseCaseNotFound().byCommand(command);
7523
}
7624

77-
commandUseCases[command]();
25+
await commandInstance.execute(context);
7826
}
7927
}

index.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ import KataService from "./domain/service/kataService/kataService";
1414
import CodewarsKataService from "./infrastructure/service/codewarsKataService";
1515
import ContentAggregatorService from "./domain/service/contentAggregatorService/contentAggregatorService";
1616
import LemmyContentAggregatorService from "./infrastructure/service/lemmyContentAggregatorService";
17+
import CodewarsLeaderboardCommand from "./application/command/codewarsLeaderboardCommand";
18+
import DontAskToAskCommand from "./application/command/dontAskToAskCommand";
19+
import OnlyCodeQuestionsCommand from "./application/command/onlyCodeQuestionsCommand";
20+
import { Command } from "./types";
1721

1822
dotenv.config();
1923

@@ -29,12 +33,14 @@ const loggerService: LoggerService = new ConsoleLoggerService();
2933
const channelResolver: ChannelResolver = new ChannelResolver();
3034
const kataService: KataService = new CodewarsKataService();
3135
const lemmyContentAggregatorService: ContentAggregatorService = new LemmyContentAggregatorService();
36+
const commands: Command[] = [
37+
new CodewarsLeaderboardCommand(chatService, kataService),
38+
new DontAskToAskCommand(chatService),
39+
new OnlyCodeQuestionsCommand(chatService),
40+
];
3241
const useCaseResolver = new CommandUseCaseResolver({
33-
messageRepository,
34-
chatService,
42+
commands,
3543
loggerService,
36-
channelResolver,
37-
kataService,
3844
});
3945

4046
const checkForNewPosts = async () => {
@@ -58,7 +64,7 @@ const checkForNewPosts = async () => {
5864
};
5965

6066
last5MinutesPosts.forEach((post) => {
61-
const title = avoidEmbedInLink(post!.getTitle());
67+
const title = avoidEmbedInLink(post.getTitle());
6268

6369
const message = `Novo post no Lemmy: **${title}** (*${post?.getAuthorName()}*)
6470

0 commit comments

Comments
 (0)