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_WEBHOOK_URL=
DISCORD_MENTION= DISCORD_MENTION=
DISCORD_REWARDS_GIVER= DISCORD_REWARDS_GIVER=
DISCORD_STAFF_ROLE_ID=""
# Postgres database url # Postgres database url
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 type { Command } from "~/commands";
import { getAccountBalance, setAccountBalance } from "~/services/account"; import { getAccountBalance, setAccountBalance } from "~/services/account";
import { getClanMembers } from "~/services/wov"; import { getClanMembers } from "~/services/wov";
import { createErrorEmbed } from "~/utils/discord"; import { replyError } from "~/utils/discord";
const STAFF_ROLE_ID = "1147963065640439900";
export const gemmesCommand: Command = async (message, args) => { 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; const displayName = message.member?.displayName || message.author.username;
let playerName = displayName.replace("🕸 |", "").trim(); const playerName = args[0] || displayName.replace("🕸 |", "").trim();
if (args.length >= 1) {
playerName = args[0]; // get clan member
const clanMembers = await getClanMembers();
const clanMember = clanMembers.find((x) => x.username === playerName);
if (!clanMember) {
await replyError(
message,
`\`${playerName}\` n'est pas dans le clan (la honte).\n**Attention les majuscules sont importantes**`,
);
return;
} }
const clanMembers = await getClanMembers(); // handle balance modification (staff only)
if (args.length === 2) {
let clanMember = clanMembers.find((x) => x.username === playerName); if (!message.member?.roles.cache.has(env.DISCORD_STAFF_ROLE_ID)) {
if (!clanMember) { await replyError(
await message.reply( message,
createErrorEmbed( "Tu t'es cru chez mémé ou quoi faut être staff",
`\`${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(
"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),
); );
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 balance = await getAccountBalance(clanMember.playerId); const balance = await getAccountBalance(clanMember.playerId);
await message.reply({ const delta = amount * (op === "+" ? 1 : -1);
embeds: [ await setAccountBalance(clanMember.playerId, Math.max(0, balance + delta));
{
description: `### 💎 Compte de ${playerName}\n\n\nGemmes disponibles: **${balance}**\n\n-# Voir avec <@294871767820795904> pour échanger contre skin/carte etc`,
color: 4360641,
},
],
});
} }
// display balance
const balance = await getAccountBalance(clanMember.playerId);
await message.reply({
embeds: [
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_MENTION: z.string(),
DISCORD_REWARDS_GIVER: z.string(), DISCORD_REWARDS_GIVER: z.string(),
DISCORD_REWARDS_CHANNEL: z.string(), DISCORD_REWARDS_CHANNEL: z.string(),
// TODO: remove and compose from staff role id
DISCORD_ADMIN_MENTION: z.string(), DISCORD_ADMIN_MENTION: z.string(),
// TODO: rename to reward ask channel or smth
DISCORD_ADMIN_CHANNEL: z.string(), DISCORD_ADMIN_CHANNEL: z.string(),
DISCORD_TRACKING_CHANNEL: z.string(), DISCORD_TRACKING_CHANNEL: z.string(),
DISCORD_STAFF_ROLE_ID: z.string(),
WOV_API_KEY: z.string(), WOV_API_KEY: z.string(),
WOV_CLAN_ID: z.string(), WOV_CLAN_ID: z.string(),
WOV_FETCH_INTERVAL: z.coerce.number(), WOV_FETCH_INTERVAL: z.coerce.number(),

View File

@@ -1,7 +1,7 @@
import { getAccountBalance, setAccountBalance } from "~/services/account"; import { getAccountBalance, setAccountBalance } from "~/services/account";
import { env } from "~/env"; import { env } from "~/env";
import type { QuestResult } from "~/services/wov"; 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 ( export const makeResultEmbed = async (
result: QuestResult, 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));