nuno 已修改 4 weeks ago. 還原成這個修訂版本
1 file changed, 46 insertions
post.ts(檔案已創建)
| @@ -0,0 +1,46 @@ | |||
| 1 | + | import { ChatInputCommandInteraction, TextChannel, EmbedBuilder } from "discord.js"; | |
| 2 | + | import { cfg } from "../../systems/config"; | |
| 3 | + | import { loadResult, todayString } from "../../systems/history"; | |
| 4 | + | import { normalizeSlot, detectSlot } from "../../systems/scores"; | |
| 5 | + | import { replyAndDelete } from "../../utils"; | |
| 6 | + | ||
| 7 | + | export async function handleResultPost(interaction: ChatInputCommandInteraction): Promise<void> { | |
| 8 | + | const slotArg = interaction.options.getString("slot"); | |
| 9 | + | ||
| 10 | + | let slot: number | null = null; | |
| 11 | + | if (slotArg) { | |
| 12 | + | slot = normalizeSlot(slotArg); | |
| 13 | + | if (slot === null) return void replyAndDelete(interaction, `❌ Could not parse slot "${slotArg}".`); | |
| 14 | + | } else { | |
| 15 | + | slot = detectSlot() ?? cfg("slots")[0]?.tgHour ?? 20; | |
| 16 | + | } | |
| 17 | + | ||
| 18 | + | const result = loadResult(todayString(), slot); | |
| 19 | + | if (!result) return void replyAndDelete(interaction, `❌ No result found for ${slot}:00 TG.`); | |
| 20 | + | ||
| 21 | + | const kd = result.nationKD; | |
| 22 | + | ||
| 23 | + | const formatScores = (nation: "Capella" | "Procyon"): string => { | |
| 24 | + | const scores = result.scores.filter((s) => s.nation === nation); | |
| 25 | + | if (scores.length === 0) return "—"; | |
| 26 | + | return scores | |
| 27 | + | .sort((a, b) => b.pts - a.pts) | |
| 28 | + | .map((s) => `**${s.characterName}** (${s.class}) — ${s.pts} pts`) | |
| 29 | + | .join("\n"); | |
| 30 | + | }; | |
| 31 | + | ||
| 32 | + | const embed = new EmbedBuilder() | |
| 33 | + | .setTitle(`⚔️ TG Results — ${result.date} ${slot}:00`) | |
| 34 | + | .setColor(0xe8a317) | |
| 35 | + | .addFields( | |
| 36 | + | { name: "🔵 Capella", value: `${kd.capella.k}K / ${kd.capella.d}D\n${formatScores("Capella")}`, inline: true }, | |
| 37 | + | { name: "🔴 Procyon", value: `${kd.procyon.k}K / ${kd.procyon.d}D\n${formatScores("Procyon")}`, inline: true }, | |
| 38 | + | ) | |
| 39 | + | .setFooter({ text: `Source of truth: ${kd.source}` }) | |
| 40 | + | .setTimestamp(); | |
| 41 | + | ||
| 42 | + | const channelId = cfg("resultsChannelId") || cfg("pollChannelId"); | |
| 43 | + | const channel = await interaction.client.channels.fetch(channelId) as TextChannel; | |
| 44 | + | await channel.send({ embeds: [embed] }); | |
| 45 | + | return void replyAndDelete(interaction, "✅ Results posted."); | |
| 46 | + | } | |
上一頁
下一頁