Skip to content

Feature/18/add block command #23

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ Para rodar no ambiente de testes, utilize `npm run dev` (irá funcionar como o N

- /help => Mostra os comandos disponíveis.

- ### Admin-Only

- /advert @username => Envia uma advertência para um usuário alvo. Ao receber 3, a conta dele será bloquada

- /block @username => Bloqueia um usário, impedindo o de usar sua conta ou recria-la.

automaticamente.

## Estrutura do projeto

- **commands**
Expand Down
6 changes: 4 additions & 2 deletions src/commands/command-execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
startCommand,
pokeCommand,
deleteCommand,
profileCommand
profileCommand,
blockCommand,
} from './resolvers';

export const commandExecuter: CommandExecuter = {
Expand All @@ -28,5 +29,6 @@ export const commandExecuter: CommandExecuter = {
friends: friendsCommand,
poke: pokeCommand,
notify: notifyCommand,
profile: profileCommand
profile: profileCommand,
block: blockCommand,
};
131 changes: 131 additions & 0 deletions src/commands/resolvers/block.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { CommandStateResolver } from '../../models/commands';
import { ApproximaClient } from '../../services/client';
import { IUser } from '../../models/user';

interface IAdmin {
name: string;
telegramId: number;
}

interface IBlockContext {
admins: IAdmin[];
isTest: boolean;
}

interface IChosenUserContext {
chosenUser: IUser;
}

const handleUserToBlock = async (client: ApproximaClient, username: string | undefined) => {

const { currentUser, context } = client.getCurrentState<IChosenUserContext>();

if (username === undefined) return 'CHOICE_USER';

if (!username.startsWith('@')) {
/* eslint-disable max-len */
const reply = 'Você precisa colocar um "@" antes do username para que funcione!\n' +
'Caso o usuário não possua um username com @ no começo, não será possível realizar essa ação.\n\n' +
'Envie um ponto (.) caso não queira mais prosseguir com o bloqueio.';
/* eslint-enable max-len */

client.sendMessage(reply);
return 'CHOICE_USER';
}

if (currentUser.username === username) {
client.sendMessage('Você não pode dar poke em si mesmo!');
return 'CHOICE_USER';
}

const user = await client.db.user.getByUsername(username);

if (!user) {
client.sendMessage('O usuário solicitado não existe :/\nEnvie sua resposta novamente.\n');
client.registerAction('block_command', {
target: username, exists: false
});

return 'CHOICE_USER' as const;

}
else if (user.blocked === true && user.active === false) {
client.sendMessage('Usuário ' + user.username + ' já está bloquado.\n\n');

return 'END';
}

context.chosenUser = user;

//
const response = 'Digite a mensagem que o usuário sobre o motivo do bloqueio.\n' +
'Para deixar em branco, envie uma virgula \',\'.\n\n' +
'Envie um ponto (.) caso não queira mais prosseguir com o bloqueio.';

client.sendMessage(response);

return 'SEND' as const;
};


export const blockCommand: CommandStateResolver<'block'> = {
// arg => Nome do usuario que deseja bloquear
INITIAL: async (client, _arg, originalArg) => {
let isAdmin = false;

const state = client.getCurrentState<IBlockContext>();

// Confere se o user é admin
state.context.admins = JSON.parse(process.env.ADMINS!);

for (const admin of state.context.admins) {
if (client.userId == admin.telegramId) {
isAdmin = true;
break;
}
}
if (!isAdmin) {
const response = 'O que você está tentando fazer? Esse comando é só para admins.';
client.sendMessage(response);

return 'END' as const;
}

// Se tiver um argumento o usuario ja escolheu alguem para dar poke
if (originalArg != undefined && originalArg != '') {
return handleUserToBlock(client, originalArg);
}

const response = 'Agora, me fale o username (@algoaqui) do usuário que você quer bloquear!\n' +
'Envie um ponto (.) caso tenha desistido.';
client.sendMessage(response);

return 'CHOICE_USER' as const;
},
CHOICE_USER: async (client, arg, originalArg) => {
if (arg === '.') {
client.sendMessage('Ok! Não vou prosseguir com o bloqueio.');
return 'END';
}
return handleUserToBlock(client, originalArg);
},
SEND: async (client, arg, originalArg) => {
const { currentUser, context } = client.getCurrentState<IChosenUserContext>();

if (arg === '.') {
client.sendMessage('Ok! Não vou prosseguir com o bloqueio.');
return 'END';
}

// Blocking the user and turn it inactive
client.db.user.edit(context.chosenUser._id, { blocked: true, active: false });
client.sendMessage(`${currentUser.username}: ` + originalArg,
undefined,
{ chatId: context.chosenUser.chat_id });
client.sendMessage('Bloqueio efetuado.\n');
client.registerAction('block_command', {
target: context.chosenUser.username, exists: true
});
return 'END' as const;
}
};
1 change: 1 addition & 0 deletions src/commands/resolvers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export { notifyCommand } from './notify';
export { pokeCommand } from './poke';
export { deleteCommand } from './delete';
export { profileCommand } from './profile';
export { blockCommand } from './block';
10 changes: 9 additions & 1 deletion src/commands/resolvers/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@ export const startCommand: CommandStateResolver<'start'> = {
let newUser = false;

if (user) {
if (user.active) {
if (user.blocked) {
const message = 'Infelizmente você não está autorizado a usar este serviço\n' +
'Boa sorte.\n';

client.sendMessage(message);
return 'END';
}
else if (user.active) {
client.registerAction('start_command', { new_user: newUser });

const message = 'É muito bom ter você de volta! Bora começar a usar o Approxima :)\n' +
Expand Down Expand Up @@ -127,6 +134,7 @@ export const startCommand: CommandStateResolver<'start'> = {
pending: [],
connections: [],
active: true,
blocked: false,
updated_at: new Date()
});

Expand Down
3 changes: 2 additions & 1 deletion src/data/commands-and-states.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ export const commandsAndStates = {
friends: ['CHOOSE_PAGE'],
poke: ['CHOOSE_USER', 'CHOOSE_MODE'],
notify: ['SEND'],
profile: []
profile: [],
block: ['CHOICE_USER', 'SEND'],
} as const;
4 changes: 2 additions & 2 deletions src/database/controllers/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ export class UserController {
}
}

getByUsername = async (username: string): Promise<IUser | undefined> => {
getByUsername = async (username: string, active: boolean = true): Promise<IUser | undefined> => {
try {
const data = await this.userRepository.getByUsername(username);
const data = await this.userRepository.getByUsername(username, active);
if (!data) {
throw new Error('User not found');
}
Expand Down
4 changes: 2 additions & 2 deletions src/database/repositories/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ export class UserRepository {
}
}

getByUsername = async (username: string): Promise<IUser | null> => {
getByUsername = async (username: string, active: boolean = true): Promise<IUser | null> => {
const encryptedUsername = await encrypt(username);
return this.usersCollection.findOne({
username: encryptedUsername,
active: true
active: active
}).then(decryptUser);
}

Expand Down
1 change: 1 addition & 0 deletions src/models/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const stateActions = [
'delete_command',
'common_prefs',
'profile_command',
'block_command',
] as const;

export type StatsActions = typeof stateActions[number];
Expand Down
2 changes: 2 additions & 0 deletions src/models/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ export interface IUser {
connections: number[];
pokes?: number[];
active: boolean;
blocked: boolean;

updated_at: Date;
}