me after S3ing my shitpost

This commit is contained in:
amy 2025-05-13 04:13:49 +03:30
parent 13457c3fbe
commit 6ff915efca
No known key found for this signature in database
8 changed files with 1259 additions and 8 deletions

View file

@ -9,6 +9,7 @@
"check": "tsc" "check": "tsc"
}, },
"dependencies": { "dependencies": {
"@aws-sdk/client-s3": "^3.808.0",
"@types/node": "^22.14.0", "@types/node": "^22.14.0",
"acorn": "^8.14.1", "acorn": "^8.14.1",
"astring": "^1.9.0", "astring": "^1.9.0",

1180
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
import { ApplicationCommandType, type AutocompleteFocusedOption, AutocompleteInteraction, ChatInputCommandInteraction, ContextMenuCommandBuilder, ContextMenuCommandInteraction, Message, SharedSlashCommand, User } from "discord.js"; import { ApplicationCommandType, type AutocompleteFocusedOption, AutocompleteInteraction, ChatInputCommandInteraction, ContextMenuCommandBuilder, ContextMenuCommandInteraction, Message, SharedSlashCommand, User } from "discord.js";
import { type Config } from "./config.ts"; import { type Config } from "./config.ts";
import type {S3Client} from "@aws-sdk/client-s3";
export abstract class ICommand { } export abstract class ICommand { }
@ -13,8 +14,8 @@ export abstract class ContextCommand<T extends User | Message> extends ICommand
} }
export abstract class Command extends ICommand { export abstract class Command extends ICommand {
abstract run(interaction: ChatInputCommandInteraction, config: Config): Promise<void>; abstract run(interaction: ChatInputCommandInteraction, config: Config, s3: S3Client): Promise<void>;
autoComplete(interaction: AutocompleteInteraction, config: Config, option: AutocompleteFocusedOption): Promise<void> { autoComplete(interaction: AutocompleteInteraction, config: Config, option: AutocompleteFocusedOption, s3: S3Client): Promise<void> {
throw new Error("Autocompletion called on command that does not have #autoComplete implemented."); throw new Error("Autocompletion called on command that does not have #autoComplete implemented.");
} }
abstract slashCommand: SharedSlashCommand abstract slashCommand: SharedSlashCommand

View file

@ -14,7 +14,7 @@ export default class FediemojiCommand extends Command {
return typedEmojis return typedEmojis
} }
async run(interaction: ChatInputCommandInteraction, config: Config) { async run(interaction: ChatInputCommandInteraction, config: Config, ) {
await interaction.deferReply(); await interaction.deferReply();
const emojiname = interaction.options.getString("emoji"); const emojiname = interaction.options.getString("emoji");
const shit = await interaction.client.application.emojis.fetch(); const shit = await interaction.client.application.emojis.fetch();

View file

@ -13,6 +13,7 @@ import {
import {getSongOnPreferredProvider, kyzaify} from "../helper.ts" import {getSongOnPreferredProvider, kyzaify} from "../helper.ts"
import {type Config} from "../config.ts"; import {type Config} from "../config.ts";
import type {S3Client} from "@aws-sdk/client-s3";
function keepV(url: string): string { function keepV(url: string): string {
const urlObj = new URL(url); const urlObj = new URL(url);
@ -28,12 +29,11 @@ function keepV(url: string): string {
} }
export default class PingCommand extends Command { export default class PingCommand extends Command {
async run(interaction: ChatInputCommandInteraction, config: Config) { async run(interaction: ChatInputCommandInteraction, config: Config, s3: S3Client): Promise<void> {
await interaction.deferReply() await interaction.deferReply()
const user = interaction.options.getString("user") ?? config.listenbrainzAccount; const user = interaction.options.getString("user") ?? config.listenbrainzAccount;
const usesonglink = interaction.options.getBoolean("usesonglink") ?? true const usesonglink = interaction.options.getBoolean("usesonglink") ?? true
const useitunes = interaction.options.getBoolean("useitunes") ?? true const useitunes = interaction.options.getBoolean("useitunes") ?? true
const meow = await fetch(`https://api.listenbrainz.org/1/user/${user}/playing-now`).then((res) => res.json()); const meow = await fetch(`https://api.listenbrainz.org/1/user/${user}/playing-now`).then((res) => res.json());
if (!meow) { if (!meow) {
await interaction.followUp("something shat itself!"); await interaction.followUp("something shat itself!");

58
src/commands/shitpost.ts Normal file
View file

@ -0,0 +1,58 @@
import {Command} from "../command.ts";
import {
ApplicationIntegrationType, AttachmentBuilder, type AutocompleteFocusedOption, AutocompleteInteraction,
ChatInputCommandInteraction,
InteractionContextType,
SlashCommandBuilder
} from "discord.js";
import { config, type Config } from "../config.ts";
import {ListObjectsV2Command, type S3Client} from "@aws-sdk/client-s3";
import {inspect} from "node:util";
export default class ShitPostCommand extends Command {
async run(interaction: ChatInputCommandInteraction, config: Config, s3: S3Client) {
const shitpost = interaction.options.getString("shitpost")!;
const shitpostUrl = "https://sp.amy.rip/" + encodeURIComponent(shitpost);
try {
const response = await fetch(shitpostUrl);
if (!response.ok) {
await interaction.reply({ content: "S3 bucket shat itself??????" });
return;
}
const buffer = await response.arrayBuffer();
const attachment = new AttachmentBuilder(Buffer.from(buffer), { name: shitpost });
await interaction.reply({ files: [attachment] });
} catch (error) {
await interaction.reply({ content: "fileproccessing shat itself" });
}
}
async autoComplete(interaction: AutocompleteInteraction, config: Config, option: AutocompleteFocusedOption, s3: S3Client): Promise<void> {
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 })))
}
slashCommand = new SlashCommandBuilder()
.setName("shitpost")
.setDescription("shitpost with S3!!!!!").setIntegrationTypes([
ApplicationIntegrationType.UserInstall
]).addStringOption(option => {
return option.setName("shitpost").setRequired(true).setDescription("the shitposts name")
.setAutocomplete(true)
})
.setContexts([
InteractionContextType.BotDM,
InteractionContextType.Guild,
InteractionContextType.PrivateChannel
]);
}

View file

@ -5,7 +5,9 @@ const configT = z.object({
listenbrainzAccount: z.string(), listenbrainzAccount: z.string(),
gitapi: z.string(), gitapi: z.string(),
sharkeyInstance:z.string(), sharkeyInstance:z.string(),
// applicationid: z.string(), R2AccountID: z.string(),
R2AccessKeyId: z.string(),
R2SecretAccessKey: z.string(),
}); });
export type Config = z.infer<typeof configT>; export type Config = z.infer<typeof configT>;
export const config: Config = configT.parse(rawconfig); export const config: Config = configT.parse(rawconfig);

View file

@ -10,6 +10,7 @@ import fs from "node:fs";
import { Command, ContextCommand, ICommand } from "./command.ts"; import { Command, ContextCommand, ICommand } from "./command.ts";
import { fileURLToPath } from "url"; import { fileURLToPath } from "url";
import { config } from "./config.ts"; import { config } from "./config.ts";
import {ListObjectsV2Command, S3Client} from "@aws-sdk/client-s3";
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename); const __dirname = path.dirname(__filename);
@ -20,6 +21,14 @@ const client = new Client({
const allCommands: ICommand[] = [] const allCommands: ICommand[] = []
const S3 = new S3Client({
region: "auto",
endpoint: `https://${config.R2AccountID}.r2.cloudflarestorage.com`,
credentials: {
accessKeyId: config.R2AccessKeyId,
secretAccessKey: config.R2SecretAccessKey,
},
});
const commandDir = path.join(__dirname, "commands"); const commandDir = path.join(__dirname, "commands");
for (const file of fs.readdirSync(commandDir)) { for (const file of fs.readdirSync(commandDir)) {
if (!file.endsWith('.ts')) continue if (!file.endsWith('.ts')) continue
@ -89,7 +98,7 @@ client.on(Events.InteractionCreate, async (interaction) => {
} }
try { try {
await command.run(interaction, config); await command.run(interaction, config, S3);
} catch (e) { } catch (e) {
console.error("error during command execution: " + commandName, e) console.error("error during command execution: " + commandName, e)
interaction.reply("something sharted itself") interaction.reply("something sharted itself")
@ -108,7 +117,7 @@ client.on(Events.InteractionCreate, async (interaction) => {
} }
try { try {
await command.autoComplete(interaction, config, interaction.options.getFocused(true)); await command.autoComplete(interaction, config, interaction.options.getFocused(true), S3);
} catch (e) { } catch (e) {
console.error("error during command execution: " + commandName, e) console.error("error during command execution: " + commandName, e)
} }