Skip to content

Commit

Permalink
feat: add coin and balance operations
Browse files Browse the repository at this point in the history
  • Loading branch information
Guilhermeasper committed Mar 26, 2024
1 parent 5699b60 commit 5c32123
Show file tree
Hide file tree
Showing 6 changed files with 546 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/bot/commands/slashCommands/balance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { SlashCommandBuilder, EmbedBuilder, GuildMember } from 'discord.js';

import { SlashCommand } from '@marquinhos/types';
import { getCoinBalance } from '@marquinhos/services/coinBalanceManager';

export const balance: SlashCommand = {
command: new SlashCommandBuilder()
.setName('saldo')
.setDescription('Retorna o seu saldo de moedas'),
execute: async (interaction) => {
const balance = await getCoinBalance(
interaction.user.id,
interaction.guild?.id ?? ''
);

const balanceEmbed = new EmbedBuilder();

balanceEmbed
.setColor('#0099ff')
.setThumbnail(interaction.user.displayAvatarURL())
.setTimestamp()
.setFooter({
text: 'Marquinhos Bot ™️',
iconURL: interaction.client.user?.displayAvatarURL(),
});

if (balance === null) {
balanceEmbed
.setTitle('Sem saldo')
.setDescription(
'Você ainda não possui saldo. Tente ganhar quinhões fazendo atividades no servidor para ganhar moedas.'
);
} else {
balanceEmbed
.setTitle(
`Saldo de ${
(interaction.member as GuildMember).nickname ??
interaction.user.username
}`
)
.addFields({
name: 'Saldo Atual',
value: `:coin: ${formatBalance(balance)}`,
inline: true,
});
}

interaction.reply({ embeds: [balanceEmbed] });
},
cooldown: 10,
};

function formatBalance(amount: Number) {
if (amount === 0) return '0 Quinhões';
if (amount === 1) return '1 Quinhão';
return `${amount} Quinhões`;
}
222 changes: 222 additions & 0 deletions src/bot/commands/slashCommands/balanceOperation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
import { SlashCommandBuilder } from '@discordjs/builders';
import {
addCoins,
resetCoins,
subtractCoins,
updateCoinBalance,
} from '@marquinhos/services/coinBalanceManager';
import { BalanceChangeStatus, BalanceOperationType } from '@marquinhos/types';
import {
BaseInteraction,
CommandInteraction,
CommandInteractionOptionResolver,
EmbedBuilder,
PermissionsBitField,
} from 'discord.js';

export const balanceOperation = {
command: new SlashCommandBuilder()
.setName('atualizar-saldo')
.setDescription('Execute operações no saldo')
.addSubcommand((subcommand) =>
subcommand
.setName('adicionar')
.setDescription('Adiciona moedas ao saldo')
.addIntegerOption((option) =>
option
.setName('valor')
.setDescription('A quantidade de moedas a adicionar')
.setRequired(true)
)
.addUserOption((option) =>
option
.setName('usuário')
.setDescription('O usuário que receberá as moedas')
.setRequired(true)
)
)
.addSubcommand((subcommand) =>
subcommand
.setName('subtrair')
.setDescription('Subtrai moedas do saldo')
.addIntegerOption((option) =>
option
.setName('valor')
.setDescription('A quantidade de moedas a subtrair')
.setRequired(true)
)
.addUserOption((option) =>
option
.setName('usuário')
.setDescription('O usuário que terá as moedas subtraídas')
.setRequired(true)
)
)
.addSubcommand((subcommand) =>
subcommand
.setName('definir')
.setDescription('Define um novo saldo')
.addIntegerOption((option) =>
option
.setName('valor')
.setDescription('O novo saldo')
.setRequired(true)
)
.addUserOption((option) =>
option
.setName('usuário')
.setDescription('O usuário que terá o saldo definido')
.setRequired(true)
)
)
.addSubcommand((subcommand) =>
subcommand
.setName('remover')
.setDescription('Apaga o saldo atual')
.addUserOption((option) =>
option
.setName('usuário')
.setDescription('O usuário que terá o saldo apagado')
.setRequired(true)
)
)
.setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator),
execute: async (interaction: CommandInteraction) => {
const subcommand = (
interaction.options as CommandInteractionOptionResolver
).getSubcommand();

const amount = interaction.options.get('valor')?.value as number;

const baseEmbed = new EmbedBuilder()
.setColor('#0099ff')
.setTitle('Operação no saldo')
.setTimestamp()
.setFooter({
text: 'Marquinhos Bot ™️',
iconURL: interaction.client.user?.displayAvatarURL(),
});

let operationResult: BalanceChangeStatus & {
operationType: BalanceOperationType | null;
} = {
operationSuccess: false,
statementCreated: false,
validAmount: false,
operationType: null,
};
const user = interaction.options.get('usuário')?.user;

switch (subcommand) {
case 'adicionar': {
operationResult = {
...(await addCoins(
user?.id ?? '',
interaction.guild?.id ?? '',
amount,
interaction.user.id
)),
operationType: 'add',
};

break;
}
case 'subtrair': {
operationResult = {
...(await subtractCoins(
user?.id ?? '',
interaction.guild?.id ?? '',
amount,
interaction.user.id
)),
operationType: 'subtract',
};
break;
}
case 'definir': {
operationResult = {
...(await updateCoinBalance(
user?.id ?? '',
interaction.guild?.id ?? '',
amount,
interaction.user.id
)),
operationType: 'set',
};
break;
}
case 'remover': {
operationResult = {
...(await resetCoins(
user?.id ?? '',
interaction.guild?.id ?? '',
interaction.user.id
)),
operationType: 'reset',
};
break;
}
}
const replyContent = operationReply(
operationResult,
amount,
user?.username ?? ''
);

baseEmbed.setTitle(replyContent.title);
baseEmbed.setDescription(replyContent.description);

await interaction.reply({
embeds: [baseEmbed],
ephemeral: true,
});
},
};

function operationReply(
operationResult: BalanceChangeStatus & {
operationType: BalanceOperationType | null;
},
amount: number,
username: string
): { title: string; description: string } {
if (operationResult.operationSuccess) {
switch (operationResult.operationType) {
case 'add':
return {
title: 'Operação bem-sucedida',
description: `Adicionado ${amount} quinhões ao saldo de ${username}.`,
};
case 'subtract':
return {
title: 'Operação bem-sucedida',
description: `Subtraido ${amount} quinhões do saldo de ${username}.`,
};
case 'reset':
return {
title: 'Operação bem-sucedida',
description: `O saldo de ${username} foi removido.`,
};
case 'set':
return {
title: 'Operação bem-sucedida',
description: `O saldo de ${username} foi definido para ${amount}.`,
};
default:
return {
title: 'Erro na operação',
description: 'Tipo de operação inválido.',
};
}
} else if (!operationResult.validAmount) {
return {
title: 'Erro na operação',
description: 'O valor deve ser um número maior que 0.',
};
} else {
return {
title: 'Erro na operação',
description: 'Ocorreu um erro ao executar a operação.',
};
}
}
2 changes: 2 additions & 0 deletions src/bot/commands/slashCommands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ export { unsilence } from '@slashCommands/unsilence';
export { toggleAdminRoulette } from '@slashCommands/toggleAdminRoulette';
export { addToRoulette } from '@slashCommands/addToRoulette';
export { audio } from '@slashCommands/audio';
export { balance } from '@slashCommands/balance';
export { balanceOperation } from '@slashCommands/balanceOperation';
28 changes: 28 additions & 0 deletions src/database/schemas/balance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Schema, model } from 'mongoose';
import { IBalance, IBalanceStatement } from '@marquinhos/types';

const BalanceSchema = new Schema<IBalance>({
userId: { required: true, type: String },
guildId: { required: true, type: String },
amount: { required: true, type: Number },
lastUpdate: { required: true, type: Date },
});

const BalanceStatementSchema = new Schema<IBalanceStatement>({
userId: { required: true, type: String },
guildId: { required: true, type: String },
amount: { required: true, type: Number },
executedBy: { required: true, type: String },
type: {
required: true,
type: String,
enum: ['add', 'subtract', 'set', 'reset'],
},
date: { required: true, type: Date },
});

const BalanceModel = model('balance', BalanceSchema);

const BalanceStatementModel = model('balanceStatement', BalanceStatementSchema);

export { BalanceModel, BalanceStatementModel };
Loading

0 comments on commit 5c32123

Please sign in to comment.