From 6ea0e02ee80588db310c0cb40db43d06b5887761 Mon Sep 17 00:00:00 2001 From: amy Date: Wed, 19 Feb 2025 15:59:18 +0330 Subject: [PATCH] of fucking course its oop again --- src/command.ts | 7 ++++ src/commands/nowplaying.ts | 79 ++++++++++++++++++++++++++++++++++++++ src/commands/ping.ts | 26 +++++++++++++ src/index.ts | 74 +++++++++++------------------------ 4 files changed, 134 insertions(+), 52 deletions(-) create mode 100644 src/command.ts create mode 100644 src/commands/nowplaying.ts create mode 100644 src/commands/ping.ts diff --git a/src/command.ts b/src/command.ts new file mode 100644 index 0000000..b13d862 --- /dev/null +++ b/src/command.ts @@ -0,0 +1,7 @@ +import {ChatInputCommandInteraction, SharedSlashCommand} from "discord.js"; + +export class Command { + constructor(){} + async run (interaction: ChatInputCommandInteraction, config): Promise{}; + slashCommand: SharedSlashCommand +} \ No newline at end of file diff --git a/src/commands/nowplaying.ts b/src/commands/nowplaying.ts new file mode 100644 index 0000000..ea1f492 --- /dev/null +++ b/src/commands/nowplaying.ts @@ -0,0 +1,79 @@ +import { Command } from "../command.ts"; +import { + ActionRowBuilder, + ApplicationIntegrationType, + ButtonBuilder, + ButtonStyle, + ChatInputCommandInteraction, + EmbedBuilder, + InteractionContextType, + SlashCommandBuilder +} from "discord.js"; + +import { getSongOnPreferredProvider } from "../helper.ts" + +function keepV(url) { + const urlObj = new URL(url); + const vParam = urlObj.searchParams.get("v"); + + urlObj.search = ""; + + if (vParam) { + urlObj.searchParams.set("v", vParam); + } + + return urlObj.toString(); +} + +export default class PingCommand extends Command { + async run(interaction: ChatInputCommandInteraction, config) { + await interaction.deferReply() + + + const meow = await fetch(`https://api.listenbrainz.org/1/user/${config.listenbrainzAccount}/playing-now`).then((res) => res.json()); + if (!meow) { + await interaction.followUp("something shat itself!"); + return; + } + if (meow.payload.count === 0) { + await interaction.followUp("user isnt listening to music"); + } else { + const track_metadata = meow.payload.listens[0].track_metadata + const link = keepV(track_metadata.additional_info.origin_url) + + const preferredApi = getSongOnPreferredProvider(await fetch(`https://api.song.link/v1-alpha.1/links?url=${link}`).then(a => a.json()), link) + if (!preferredApi) { + interaction.followUp("song not found") + return + } + const embed = new EmbedBuilder() + .setAuthor({ + name: preferredApi.artist, + }) + .setTitle(preferredApi.title) + .setThumbnail(preferredApi.thumbnailUrl) + .setFooter({ + text: "amy jr", + }); + const nya = new ActionRowBuilder().addComponents(new ButtonBuilder().setURL(preferredApi.link).setLabel("link").setStyle(ButtonStyle.Link)) + interaction.followUp({ + components: [ + nya + ], + embeds: [embed] + }); + } + + } + + slashCommand = new SlashCommandBuilder() + .setName("nowplaying") + .setDescription("balls").setIntegrationTypes([ + ApplicationIntegrationType.UserInstall + ]) + .setContexts([ + InteractionContextType.BotDM, + InteractionContextType.Guild, + InteractionContextType.PrivateChannel + ]); +} \ No newline at end of file diff --git a/src/commands/ping.ts b/src/commands/ping.ts new file mode 100644 index 0000000..179d9ab --- /dev/null +++ b/src/commands/ping.ts @@ -0,0 +1,26 @@ +import {Command} from "../command.ts"; +import { + ApplicationIntegrationType, + ChatInputCommandInteraction, + InteractionContextType, + SlashCommandBuilder +} from "discord.js"; + +export default class PingCommand extends Command { + async run(interaction: ChatInputCommandInteraction, config) { + await interaction.reply({ + content: 'Pong!', + }); + } + + slashCommand = new SlashCommandBuilder() + .setName("ping") + .setDescription("Pong!").setIntegrationTypes([ + ApplicationIntegrationType.UserInstall + ]) + .setContexts([ + InteractionContextType.BotDM, + InteractionContextType.Guild, + InteractionContextType.PrivateChannel + ]); +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 0b7964e..af63872 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,6 +16,13 @@ import { SlashCommandBuilder } from "discord.js"; import { getSongOnPreferredProvider } from "./helper.ts"; +import path from "node:path"; +import fs from "node:fs"; +import { Command } from "./command.ts"; +import { fileURLToPath } from "url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); const client = new Client({ intents: Object.keys(GatewayIntentBits).map((a) => { @@ -24,38 +31,22 @@ const client = new Client({ }), }); -function keepV(url) { - const urlObj = new URL(url); - const vParam = urlObj.searchParams.get("v"); +const commands: Command[] = [] - urlObj.search = ""; - if (vParam) { - urlObj.searchParams.set("v", vParam); - } - - return urlObj.toString(); +const commandDir = path.join(__dirname, "commands"); +for (const file of fs.readdirSync(commandDir)) { + let command = await import(path.join(commandDir, file)); + commands.push(new command.default()) } -const commands = [ - new SlashCommandBuilder().setName("nowplaying") - .setDescription("balls") - .setIntegrationTypes([ - ApplicationIntegrationType.UserInstall - ]) - .setContexts([ - InteractionContextType.BotDM, - InteractionContextType.Guild, - InteractionContextType.PrivateChannel - ]) -].map(command => command.toJSON()) - +const commandLookup = Object.fromEntries(commands.map(it => [it.slashCommand.name, it])) client.once(Events.ClientReady, async () => { console.log("Ready"); const rest = new REST().setToken(config.token); const data = await rest.put( - Routes.applicationCommands(client.user.id), { body: commands }, + Routes.applicationCommands(client.user.id), { body: commands.map(command => command.slashCommand.toJSON()) }, ); // @ts-ignore console.log(`Successfully reloaded ${data.length} application (/) commands.`); @@ -65,38 +56,17 @@ client.on(Events.InteractionCreate, async (interaction) => { if (!interaction.isChatInputCommand()) return; const { commandName } = interaction; - if (commandName !== "nowplaying") return; - await interaction.deferReply() - - const meow = await fetch(`https://api.listenbrainz.org/1/user/${config.listenbrainzAccount}/playing-now`).then((res) => res.json()); - if (!meow) { - interaction.followUp("something shat itself!"); - return; + const command = commandLookup[commandName] + if (!command) { + console.error("unknown command: " + commandName) + return } - if (meow.payload.count === 0) { - interaction.followUp("user isnt listening to music"); - } else { - const track_metadata = meow.payload.listens[0].track_metadata - const link = keepV(track_metadata.additional_info.origin_url) - const preferredApi = getSongOnPreferredProvider(await fetch(`https://api.song.link/v1-alpha.1/links?url=${link}`).then(a => a.json()), link) - const embed = new EmbedBuilder() - .setAuthor({ - name: preferredApi.artist, - }) - .setTitle(preferredApi.title) - .setThumbnail(preferredApi.thumbnailUrl) - .setFooter({ - text: "amy jr", - }); - const nya = new ActionRowBuilder().addComponents(new ButtonBuilder().setURL(preferredApi.link).setLabel("link").setStyle(ButtonStyle.Link)) - interaction.followUp({ - components: [ - nya - ], - embeds: [embed] - }); + try { + await command.run(interaction, config); + } catch { + interaction.reply("something sharted itself") } })