From 4eb781732ba0f20c12dff1cd1ac4f2fe993f15b5 Mon Sep 17 00:00:00 2001 From: amy Date: Wed, 14 May 2025 21:19:29 +0330 Subject: [PATCH] ADD TO SHITPOSTS --- src/command.ts | 2 +- src/commands/addtoshitpost.ts | 41 +++++++++++++++++++++++++++++++++++ src/commands/shitpost.ts | 21 ++++++++++-------- src/config.ts | 6 +++-- src/index.ts | 9 ++++---- 5 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 src/commands/addtoshitpost.ts diff --git a/src/command.ts b/src/command.ts index 99d4e8a..c114239 100644 --- a/src/command.ts +++ b/src/command.ts @@ -10,7 +10,7 @@ export abstract class ContextCommand extends ICommand T extends Message ? ApplicationCommandType.Message : never; abstract contextDefinition: ContextMenuCommandBuilder - abstract run(interaction: ContextMenuCommandInteraction, target: T extends User ? User : T extends Message ? Message : never): Promise + abstract run(interaction: ContextMenuCommandInteraction, target: T extends User ? User : T extends Message ? Message : never, config: Config): Promise } export abstract class Command extends ICommand { diff --git a/src/commands/addtoshitpost.ts b/src/commands/addtoshitpost.ts new file mode 100644 index 0000000..2e4a1bc --- /dev/null +++ b/src/commands/addtoshitpost.ts @@ -0,0 +1,41 @@ +import { + ApplicationCommandType, type Attachment, + ContextMenuCommandBuilder, + ContextMenuCommandInteraction, + Message +} from "discord.js"; +import { ContextCommand } from "../command.ts"; +import {PutObjectCommand, type S3Client} from "@aws-sdk/client-s3"; +import type {Config} from "../config.ts"; +import {BUCKETNAME} from "./shitpost.ts"; + +export default class Mock extends ContextCommand { + targetType: ApplicationCommandType.Message = ApplicationCommandType.Message; + contextDefinition: ContextMenuCommandBuilder = + new ContextMenuCommandBuilder() + .setName('AddToShitposts') + .setType(ApplicationCommandType.Message) + async run(interaction: ContextMenuCommandInteraction, target: Message, config:Config): Promise { + await interaction.deferReply() + await interaction.followUp({content: "uploading..."}) + for (const [_, attachment] of target.attachments) { + + const response = await fetch(attachment.proxyURL); + + if (!response.ok) { + await interaction.reply({ content: "discord shat itself??????" }); + return; + } + + const buffer = await response.arrayBuffer(); + + const command = new PutObjectCommand({ + Bucket: BUCKETNAME, + Key: attachment.name, + Body: Buffer.from(buffer), + }); + await config.s3.send(command) + } + await interaction.editReply({content: "shits have been posted"}) + } +} \ No newline at end of file diff --git a/src/commands/shitpost.ts b/src/commands/shitpost.ts index cc477fb..b9829c6 100644 --- a/src/commands/shitpost.ts +++ b/src/commands/shitpost.ts @@ -5,15 +5,17 @@ import { InteractionContextType, SlashCommandBuilder } from "discord.js"; -import { config, type Config } from "../config.ts"; +import {config, type Config} from "../config.ts"; import {ListObjectsV2Command, type S3Client} from "@aws-sdk/client-s3"; import {inspect} from "node:util"; +export const BUCKETNAME = "shitposts" as const; export default class ShitPostCommand extends Command { async run(interaction: ChatInputCommandInteraction, config: Config, s3: S3Client) { - const shitpost = interaction.options.getString("shitpost")!; + await interaction.deferReply(); + const shitpost = interaction.options.getString("shitpost")!; const shitpostUrl = "https://sp.amy.rip/" + encodeURIComponent(shitpost); @@ -21,27 +23,28 @@ export default class ShitPostCommand extends Command { const response = await fetch(shitpostUrl); if (!response.ok) { - await interaction.reply({ content: "S3 bucket shat itself??????" }); + await interaction.followUp({content: "S3 bucket shat itself??????"}); return; } const buffer = await response.arrayBuffer(); - const attachment = new AttachmentBuilder(Buffer.from(buffer), { name: shitpost }); + const attachment = new AttachmentBuilder(Buffer.from(buffer), {name: shitpost}); - await interaction.reply({ files: [attachment] }); + await interaction.followUp({files: [attachment]}); } catch (error) { - await interaction.reply({ content: "fileproccessing shat itself" }); + await interaction.followUp({content: "fileproccessing shat itself"}); } } async autoComplete(interaction: AutocompleteInteraction, config: Config, option: AutocompleteFocusedOption, s3: S3Client): Promise { - await interaction.respond((await s3.send(new ListObjectsV2Command({ Bucket: "shitposts" }))).Contents! - .filter((i): i is { Key: string } => !!i.Key) - .map(key => ({ name: key.Key, value: key.Key }))) + await interaction.respond((await s3.send(new ListObjectsV2Command({Bucket: BUCKETNAME}))).Contents! + .filter((i): i is { Key: string } => !!i.Key) + .map(key => ({name: key.Key, value: key.Key}))) } + slashCommand = new SlashCommandBuilder() .setName("shitpost") .setDescription("shitpost with S3!!!!!").setIntegrationTypes([ diff --git a/src/config.ts b/src/config.ts index 5d28678..85b8b8e 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,5 +1,6 @@ import rawconfig from "../config.json" with {type: "json"}; import {z} from 'zod'; +import type {S3Client} from "@aws-sdk/client-s3"; const configT = z.object({ token: z.string(), listenbrainzAccount: z.string(), @@ -9,7 +10,8 @@ const configT = z.object({ R2AccessKeyId: z.string(), R2SecretAccessKey: z.string(), }); -export type Config = z.infer; -export const config: Config = configT.parse(rawconfig); +export type RawConfig = z.infer; +export type Config = RawConfig & {s3: S3Client} +export const config: RawConfig = configT.parse(rawconfig); diff --git a/src/index.ts b/src/index.ts index 5a1fc73..5729db4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,7 +9,7 @@ import path from "node:path"; import fs from "node:fs"; import { Command, ContextCommand, ICommand } from "./command.ts"; import { fileURLToPath } from "url"; -import { config } from "./config.ts"; +import {type Config, config} from "./config.ts"; import {ListObjectsV2Command, S3Client} from "@aws-sdk/client-s3"; const __filename = fileURLToPath(import.meta.url); @@ -29,6 +29,7 @@ const S3 = new S3Client({ secretAccessKey: config.R2SecretAccessKey, }, }); +const enrichedConfig = {...config, s3:S3} satisfies Config; const commandDir = path.join(__dirname, "commands"); for (const file of fs.readdirSync(commandDir)) { if (!file.endsWith('.ts')) continue @@ -80,7 +81,7 @@ client.on(Events.InteractionCreate, async (interaction) => { if (command.targetType != (interaction.isUserContextMenuCommand() ? ApplicationCommandType.User : ApplicationCommandType.Message)) console.error("Out of date discord definition of this context command") try { - await command.run(interaction, interaction.isUserContextMenuCommand() ? interaction.targetUser : interaction.targetMessage) + await command.run(interaction, interaction.isUserContextMenuCommand() ? interaction.targetUser : interaction.targetMessage, enrichedConfig) } catch (e) { console.error("error during context command execution: " + commandName, e) interaction.reply("something sharted itself") @@ -98,7 +99,7 @@ client.on(Events.InteractionCreate, async (interaction) => { } try { - await command.run(interaction, config, S3); + await command.run(interaction, enrichedConfig, S3); } catch (e) { console.error("error during command execution: " + commandName, e) interaction.reply("something sharted itself") @@ -117,7 +118,7 @@ client.on(Events.InteractionCreate, async (interaction) => { } try { - await command.autoComplete(interaction, config, interaction.options.getFocused(true), S3); + await command.autoComplete(interaction, enrichedConfig, interaction.options.getFocused(true), S3); } catch (e) { console.error("error during command execution: " + commandName, e) }