Files
blitzkit/packages/bot/src/commands/auction.ts
T

144 lines
4.1 KiB
TypeScript
Raw Normal View History

2024-12-13 10:58:16 -06:00
import {
BlitzTankClass,
Region,
regionToRegionSubdomain,
} from '@blitzkit/core';
2025-01-15 20:14:05 -06:00
import { literals } from '@blitzkit/i18n';
2024-12-13 10:58:16 -06:00
import { tankDefinitions } from '../core/blitzkit/nonBlockingPromises';
2024-12-14 14:41:50 -06:00
import { chunkLines } from '../core/discord/chunkLines';
2024-12-13 10:58:16 -06:00
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
import { translator } from '../core/localization/translator';
import { CommandRegistry } from '../events/interactionCreate';
2025-01-16 14:22:30 -06:00
type Auction = null | {
2024-12-13 10:58:16 -06:00
count: number;
has_next: boolean;
results: Result[];
2025-01-16 14:22:30 -06:00
};
2024-12-13 10:58:16 -06:00
type Result =
| {
id?: number;
type: 'vehicle';
countable?: boolean;
entity?: Entity;
2024-12-13 16:25:37 -06:00
initial_count: number;
current_count: number;
2024-12-13 10:58:16 -06:00
saleable?: boolean;
available_from?: Date;
available_before?: Date;
price?: Price;
2024-12-16 10:41:10 -06:00
next_price: Price | null;
2024-12-13 10:58:16 -06:00
available: true;
display?: boolean;
2024-12-13 16:11:43 -06:00
next_price_datetime: Date;
next_price_timestamp: number;
2024-12-13 10:58:16 -06:00
}
| {
available: false;
type: 'vehicle';
};
interface Entity {
id: number;
name: string;
nation: string;
subnation: string;
use_subnation_flag: boolean;
type_slug: BlitzTankClass;
level: number;
roman_level: string;
user_string: string;
image_url: string;
preview_image_url: string;
is_premium: boolean;
is_collectible: boolean;
}
interface Price {
currency: Currency;
value: number;
}
interface Currency {
name: 'gold';
count: number;
title: 'Gold';
image_url: string;
sizes: unknown;
type: 'currency';
}
2024-12-15 19:06:05 -06:00
const WARNING_COUNT = 500;
2024-12-13 10:58:16 -06:00
export const auctionCommand = new Promise<CommandRegistry>((resolve) => {
resolve({
2024-12-13 16:11:43 -06:00
command: createLocalizedCommand('auction'),
2024-12-13 10:58:16 -06:00
async handler(interaction) {
2025-01-15 20:14:05 -06:00
const { strings } = translator(interaction.locale);
2024-12-13 10:58:16 -06:00
const awaitedTankDefinitions = await tankDefinitions;
const region: Region = 'com';
const pageSize = 80;
const saleable = true;
const data = await fetch(
`https://${regionToRegionSubdomain(
region,
)}.wotblitz.com/en/api/events/items/auction/?page_size=${
pageSize
}&type[]=vehicle&saleable=${saleable}`,
).then((response) => response.json() as Promise<Auction>);
2025-01-16 14:22:30 -06:00
if (data === null) {
2025-01-15 20:14:05 -06:00
return strings.bot.commands.auction.errors.no_auction;
2024-12-13 16:11:43 -06:00
}
2025-01-16 14:22:30 -06:00
const saleableTanks = data.results.filter((result) => result.available);
2024-12-13 16:11:43 -06:00
const nextPricesTimestamp = saleableTanks[0].next_price_timestamp;
2025-01-15 20:14:05 -06:00
const title = `# ${strings.bot.commands.auction.body.title}`;
const subtitle = `${literals(strings.bot.commands.auction.body.subtitle, [
2024-12-13 16:11:43 -06:00
`${saleableTanks.length} / ${data.results.length}`,
`<t:${nextPricesTimestamp}:R>`,
'<https://wotblitz.com/auction/>',
])}`;
2024-12-14 14:41:50 -06:00
const body = saleableTanks.map((data, index) => {
const tank = awaitedTankDefinitions.tanks[data.entity!.id];
2024-12-13 10:58:16 -06:00
2024-12-14 14:41:50 -06:00
if (!tank) return '';
2024-12-13 10:58:16 -06:00
2025-05-15 23:44:20 -05:00
const name = `[${tank.name}](<https://blitzkit.app/tanks/${
tank.slug
2024-12-14 14:41:50 -06:00
}>)`;
2024-12-16 10:41:10 -06:00
const next =
data.next_price === null
? ''
2025-01-15 20:14:05 -06:00
: `\n-# ${literals(strings.bot.commands.auction.body.next, [
2024-12-16 10:41:10 -06:00
`<:gold:1317173197082333244> ${data.next_price.value.toLocaleString(
interaction.locale,
)}`,
])}`;
2025-01-15 20:14:05 -06:00
const available = literals(
strings.bot.commands.auction.body.available,
[
data.current_count.toLocaleString(interaction.locale),
data.initial_count.toLocaleString(interaction.locale),
],
);
2024-12-15 19:06:05 -06:00
const isOut = data.current_count === 0;
const outString = isOut ? '~~' : '';
const isLow = data.current_count <= WARNING_COUNT;
2024-12-13 10:58:16 -06:00
2024-12-15 19:06:05 -06:00
return `${index + 1}. ${
outString
}${name} <:gold:1317173197082333244> ${data.price!.value.toLocaleString(
2024-12-14 14:41:50 -06:00
interaction.locale,
2024-12-16 10:41:10 -06:00
)}${outString}\n-#${isLow ? ' ‼️ ' : ' '}${available}${isOut ? '' : next}`;
2024-12-14 14:41:50 -06:00
});
const header = `${title}\n${subtitle}`;
const lines = [header, ...body];
return chunkLines(lines, '\n\n');
2024-12-13 10:58:16 -06:00
},
});
});