diff --git a/.github/aoc.config.json b/.github/aoc.config.json deleted file mode 100644 index 35655a16..00000000 --- a/.github/aoc.config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "targetChannelId": "", - "sessionToken": "lol", - "leaderBoardJsonUrl": "", - "userMap": {} -} diff --git a/.github/config.json b/.github/config.json index a29c0d22..ca0a2a68 100644 --- a/.github/config.json +++ b/.github/config.json @@ -51,6 +51,13 @@ "blacklistedChannelIds": [], "defaultTargetChannelId": "893179191556706386", "targetChannelOverrides": [] + }, + "aoc": { + "enabled": false, + "targetChannelId": "", + "sessionToken": "", + "leaderBoardJsonUrl": "", + "userMap": {} } }, diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index d17f4765..1e00bda5 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -61,8 +61,6 @@ jobs: sed -i 's//${{ secrets.CI_BOT_TOKEN }}/g' config.json sed -i 's//${{ secrets.CI_CLIENT_ID }}/g' config.json - cp .github/aoc.config.json aoc.config.json - - name: Check if bot starts correctly if: ${{ github.event_name == 'push' }} run: | @@ -71,6 +69,5 @@ jobs: -e NODE_ENV=development \ -e DATABASE_PATH=:memory: \ -v "$PWD/config.json:/app/config.json" \ - -v "$PWD/aoc.config.json:/app/aoc.config.json" \ csz-bot:latest --dry-run diff --git a/.gitignore b/.gitignore index ce7e2197..b7b1639e 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,3 @@ dist *.db .idea/ built/ -aoc.config.json diff --git a/.infra/compose.yaml b/.infra/compose.yaml index ed04653a..33314fc6 100644 --- a/.infra/compose.yaml +++ b/.infra/compose.yaml @@ -9,7 +9,6 @@ services: - .env volumes: - ./config.json:/app/config.json:ro - - ./aoc.config.json:/app/aoc.config.json:ro - ./sounds:/app/sounds:ro - ./banners:/app/banners:ro - /etc/timezone:/etc/timezone:ro diff --git a/src/commands/aoc.ts b/src/commands/aoc.ts index 16cdfbc0..1c8e88b8 100644 --- a/src/commands/aoc.ts +++ b/src/commands/aoc.ts @@ -1,6 +1,3 @@ -import * as fs from "node:fs/promises"; -import * as path from "node:path"; - import { type CacheType, type CommandInteraction, @@ -14,22 +11,13 @@ import type { ApplicationCommand } from "./command.js"; import log from "@log"; -const aocConfigPath = path.resolve("aoc.config.json"); +type CompletionInfo = Record<1 | 2, { get_start_ts: number }>; -type UserMapEntry = { +export type UserMapEntry = { displayName: string; language: string; }; -type AoCConfig = { - targetChannelId: string; - sessionToken: string; - leaderBoardJsonUrl: string; - userMap: Record; -}; - -type CompletionInfo = Record<1 | 2, { get_start_ts: number }>; - type AoCMember = { id: string; name: string; @@ -46,7 +34,6 @@ type LeaderBoard = { members: Record; }; -const aocConfig = JSON.parse(await fs.readFile(aocConfigPath, "utf8")) as AoCConfig; const medals = ["🥇", "🥈", "🥉", "🪙", "🏵️", "🌹"]; const getLanguage = (member: AoCMember, userMap: Record): string => { @@ -120,10 +107,13 @@ const createEmbedFromLeaderBoard = ( }; }; -const getLeaderBoard = async (): Promise => { - const leaderBoard = (await fetch(aocConfig.leaderBoardJsonUrl, { +const getLeaderBoard = async ( + leaderBoardJsonUrl: string, + sessionToken: string, +): Promise => { + const leaderBoard = (await fetch(leaderBoardJsonUrl, { headers: { - Cookie: `session=${aocConfig.sessionToken}`, + Cookie: `session=${encodeURIComponent(sessionToken)}`, }, }).then(r => r.json())) as LeaderBoard; return leaderBoard; @@ -132,6 +122,8 @@ const getLeaderBoard = async (): Promise => { export async function publishAocLeaderBoard(context: BotContext) { log.debug("Entered `AoCHandler#publishLeaderBoard`"); + const aocConfig = context.commandConfig.aoc; + const targetChannel = context.guild.channels.cache.get(aocConfig.targetChannelId); if (!targetChannel) { log.error(`Target channel ${aocConfig.targetChannelId} not found`); @@ -139,7 +131,7 @@ export async function publishAocLeaderBoard(context: BotContext) { } const channel = targetChannel as discord.ThreadChannel; - const leaderBoard = await getLeaderBoard(); + const leaderBoard = await getLeaderBoard(aocConfig.leaderBoardJsonUrl, aocConfig.sessionToken); const embed = createEmbedFromLeaderBoard(aocConfig.userMap, leaderBoard, "local_score"); return channel.send({ embeds: [embed] }); } @@ -171,14 +163,15 @@ export default class AoCCommand implements ApplicationCommand { .setRequired(false), ); - async handleInteraction(command: CommandInteraction) { + async handleInteraction(command: CommandInteraction, context: BotContext) { if (!command.isChatInputCommand()) { // TODO: Solve this on a type level return; } - const { channel } = command; - if (!channel?.isTextBased()) { + const aocConfig = context.commandConfig.aoc; + + if (!command.channel?.isTextBased()) { await command.reply({ content: "Mach mal nicht hier", ephemeral: true, @@ -186,6 +179,14 @@ export default class AoCCommand implements ApplicationCommand { return; } + if (!aocConfig.enabled) { + await command.reply({ + content: "AoC ist gerade nicht", + ephemeral: true, + }); + return; + } + const order = command.options.getString("order", false) ?? "local_score"; if (order !== "stars" && order !== "local_score" && order !== "global_score") { @@ -193,7 +194,10 @@ export default class AoCCommand implements ApplicationCommand { throw new Error(`Invalid order ${order}`); } - const leaderBoard = await getLeaderBoard(); + const leaderBoard = await getLeaderBoard( + aocConfig.leaderBoardJsonUrl, + aocConfig.sessionToken, + ); const embed = createEmbedFromLeaderBoard(aocConfig.userMap, leaderBoard, order); await command.reply({ embeds: [embed] }); } diff --git a/src/context.ts b/src/context.ts index 0d085c2d..ffce8353 100644 --- a/src/context.ts +++ b/src/context.ts @@ -13,6 +13,7 @@ import type { import { ChannelType } from "discord.js"; import { Temporal } from "@js-temporal/polyfill"; +import type { UserMapEntry } from "./commands/aoc.js"; import { readConfig } from "./service/configService.js"; /** @@ -53,6 +54,14 @@ export interface BotContext { instagram: { rapidApiInstagramApiKey?: string; }; + aoc: { + enabled: boolean; + + targetChannelId: Snowflake; + sessionToken: string; + leaderBoardJsonUrl: string; + userMap: Record; + }; }; roles: { @@ -221,6 +230,13 @@ export async function createBotContext(client: Client): Promise; defaultTargetChannelId: Snowflake; }; + aoc: { + enabled: boolean; + + targetChannelId: Snowflake; + sessionToken: string; + leaderBoardJsonUrl: string; + userMap: Record< + Snowflake, + { + displayName: string; + language: string; + } + >; + }; }; deleteThreadMessagesInChannelIds: readonly Snowflake[];