refactor(discord-bot): improve 'gemmes' command

This commit is contained in:
Pihkaal
2025-12-05 17:11:06 +01:00
parent e7c37ff324
commit 19cb5b445b
4 changed files with 62 additions and 52 deletions

View File

@@ -9,6 +9,7 @@ QUEST_EXCLUDE=
DISCORD_WEBHOOK_URL=
DISCORD_MENTION=
DISCORD_REWARDS_GIVER=
DISCORD_STAFF_ROLE_ID=""
# Postgres database url
DATABASE_URL=""

View File

@@ -1,65 +1,62 @@
import { EmbedBuilder } from "discord.js";
import { env } from "~/env";
import type { Command } from "~/commands";
import { getAccountBalance, setAccountBalance } from "~/services/account";
import { getClanMembers } from "~/services/wov";
import { createErrorEmbed } from "~/utils/discord";
const STAFF_ROLE_ID = "1147963065640439900";
import { replyError } from "~/utils/discord";
export const gemmesCommand: Command = async (message, args) => {
// retrieve player name
// NOTE: discord members have display name formatted like "🕸 | InGamePseudo"
const displayName = message.member?.displayName || message.author.username;
let playerName = displayName.replace("🕸 |", "").trim();
if (args.length >= 1) {
playerName = args[0];
}
const playerName = args[0] || displayName.replace("🕸 |", "").trim();
// get clan member
const clanMembers = await getClanMembers();
let clanMember = clanMembers.find((x) => x.username === playerName);
const clanMember = clanMembers.find((x) => x.username === playerName);
if (!clanMember) {
await message.reply(
createErrorEmbed(
await replyError(
message,
`\`${playerName}\` n'est pas dans le clan (la honte).\n**Attention les majuscules sont importantes**`,
),
);
} else {
if (args.length === 2 && message.member) {
if (!message.member.roles.cache.has(STAFF_ROLE_ID)) {
await message.reply(
createErrorEmbed("Tu t'es cru chez mémé ou quoi faut être staff"),
);
return;
}
if (
(args[1][0] !== "+" && args[1][0] !== "-") ||
!args[1] ||
isNaN(Number(args[1].substring(1)))
) {
await message.reply(
createErrorEmbed(
// handle balance modification (staff only)
if (args.length === 2) {
if (!message.member?.roles.cache.has(env.DISCORD_STAFF_ROLE_ID)) {
await replyError(
message,
"Tu t'es cru chez mémé ou quoi faut être staff",
);
return;
}
const op = args[1][0];
const amount = Number(args[1].substring(1));
if ((op !== "+" && op !== "-") || args[1].length === 1 || isNaN(amount)) {
await replyError(
message,
"Format: `@LBF gemmes <pseudo> <+GEMMES | -GEMMES>`\nExemple: `@LBF gemmes Yuno -10000`\n**Attention les majuscules sont importantes**",
),
);
return;
}
const mult = args[1][0] === "+" ? 1 : -1;
const delta = Number(args[1].substring(1)) * mult;
const balance = await getAccountBalance(clanMember.playerId);
await setAccountBalance(
clanMember.playerId,
Math.max(0, balance + delta),
);
const delta = amount * (op === "+" ? 1 : -1);
await setAccountBalance(clanMember.playerId, Math.max(0, balance + delta));
}
// display balance
const balance = await getAccountBalance(clanMember.playerId);
await message.reply({
embeds: [
{
description: `### 💎 Compte de ${playerName}\n\n\nGemmes disponibles: **${balance}**\n\n-# Voir avec <@294871767820795904> pour échanger contre skin/carte etc`,
color: 4360641,
},
new EmbedBuilder()
.setDescription(
// TODO: mention here instead of in the env
`### 💎 Compte de ${playerName}\n\n\nGemmes disponibles: **${balance}**\n\n-# Voir avec ${env.DISCORD_REWARDS_GIVER} pour échanger contre skin/carte etc`,
)
.setColor(0x4289c1),
],
});
}
};

View File

@@ -6,9 +6,12 @@ const schema = z.object({
DISCORD_MENTION: z.string(),
DISCORD_REWARDS_GIVER: z.string(),
DISCORD_REWARDS_CHANNEL: z.string(),
// TODO: remove and compose from staff role id
DISCORD_ADMIN_MENTION: z.string(),
// TODO: rename to reward ask channel or smth
DISCORD_ADMIN_CHANNEL: z.string(),
DISCORD_TRACKING_CHANNEL: z.string(),
DISCORD_STAFF_ROLE_ID: z.string(),
WOV_API_KEY: z.string(),
WOV_CLAN_ID: z.string(),
WOV_FETCH_INTERVAL: z.coerce.number(),

View File

@@ -1,7 +1,7 @@
import { getAccountBalance, setAccountBalance } from "~/services/account";
import { env } from "~/env";
import type { QuestResult } from "~/services/wov";
import type { MessageCreateOptions, APIEmbed } from "discord.js";
import type { MessageCreateOptions, APIEmbed, Message } from "discord.js";
export const makeResultEmbed = async (
result: QuestResult,
@@ -105,3 +105,12 @@ export const createInfoEmbed = (
},
],
});
export const replyError = (message: Message, text: string, color?: number) =>
message.reply(createErrorEmbed(text, color));
export const replySuccess = (message: Message, text: string, color?: number) =>
message.reply(createSuccessEmbed(text, color));
export const replyInfo = (message: Message, text: string, color?: number) =>
message.reply(createInfoEmbed(text, color));