From 14ee0d798a97fd2e23d50e34fe4a983a112ff302 Mon Sep 17 00:00:00 2001 From: Kian Kasad Date: Thu, 2 Oct 2025 19:59:32 -0400 Subject: [PATCH] feat: add /cowsay command --- bun.lockb | Bin 95327 -> 108782 bytes package.json | 2 + src/commands/cowsay.ts | 98 +++++++++++++++++++++++++++++++++++++++++ src/commands/index.ts | 3 +- 4 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 src/commands/cowsay.ts diff --git a/bun.lockb b/bun.lockb index f32503e8ce1c55c913a81acc7296af6cc2cdec01..6572755d68a8d3e3433c8b906aa5a7e3e65a3bbc 100755 GIT binary patch delta 26424 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 delta 19296 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 diff --git a/package.json b/package.json index 739ef08..ec76334 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,12 @@ }, "dependencies": { "@aws-sdk/client-s3": "^3.717.0", + "@barudakrosul/textwrap": "^0.0.4", "@octokit/rest": "^21.0.2", "@t3-oss/env-core": "^0.11.1", "@types/sharp": "^0.32.0", "bufferutil": "^4.0.8", + "cowsay": "^1.6.0", "dayjs": "^1.11.13", "discord.js": "^14.16.3", "fastest-levenshtein": "^1.0.16", diff --git a/src/commands/cowsay.ts b/src/commands/cowsay.ts new file mode 100644 index 0000000..5becdf4 --- /dev/null +++ b/src/commands/cowsay.ts @@ -0,0 +1,98 @@ +import { + type ChatInputCommandInteraction, + SlashCommandBuilder, +} from "discord.js"; +import cowsay from "cowsay"; +import textwrap from "@barudakrosul/textwrap"; + +const DEFAULT_WRAP_WIDTH = 40; + +export const data = new SlashCommandBuilder() + .setName("cowsay") + .setDescription("Make a cow say it") + .addStringOption((option) => + option + .setName("text") + .setDescription("The text to say") + .setRequired(true), + ) + .addStringOption((option) => + option + .setName("cow") + .setDescription("The cow design to use") + .setRequired(false), + ) + .addIntegerOption((option) => + option + .setName("wrap_width") + .setDescription( + "Width at which to wrap the input text (0 to disable)", + ) + .setRequired(false), + ); + +export async function command(interaction: ChatInputCommandInteraction) { + const { options } = interaction; + + const text = options.getString("text", true); + const cow = options.getString("cow"); + const wrapWidth = options.getInteger("wrap_width") ?? DEFAULT_WRAP_WIDTH; + + const isChannel = !!interaction.channel; + + if (!isChannel) { + await interaction.reply({ + content: "This command can only be used in a channel", + ephemeral: true, + }); + return; + } + + if (text === "!list") { + for (const chunk of await getCowListResponseContent()) { + await interaction.reply({ + content: chunk, + ephemeral: true, + }); + } + } else { + await interaction.reply({ + content: getCowsayResponseContent(text, cow, wrapWidth), + }); + } +} + +function getCowsayResponseContent( + text: string, + cow: string | null, + wrapWidth: number, +): string { + const wrappedText = + wrapWidth > 0 ? textwrap.wrap(text, wrapWidth).join("\n") : text; + const cowsaid = cowsay.say({ + text: wrappedText, + f: cow ?? undefined, + }); + return "```\n" + cowsaid + "\n```"; +} + +async function getCowListResponseContent(): Promise { + try { + const filenames = await cowsay.list(() => {}); + const cows = filenames.map((name) => name.replace(/\.cow$/, "")); + const chunks = ["```\n"]; + for (const cow of cows) { + if (chunks[chunks.length - 1].length + cow.length + 1 + 3 > 2000) { + chunks[chunks.length - 1] += "```"; + chunks.push("```\n"); + } + chunks[chunks.length - 1] += cow + "\n"; + } + chunks[chunks.length - 1] += "```"; + return chunks; + } catch (e) { + const msg = (e as Error).message; + console.error(`Error listing cows: ${msg}`); + return ["Error listing cows"]; + } +} diff --git a/src/commands/index.ts b/src/commands/index.ts index 2e2e0b1..4bfc7b3 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -4,10 +4,11 @@ import type { } from "discord.js"; import * as summarize from "./summarize"; +import * as cowsay from "./cowsay"; type Command = { data: SlashCommandOptionsOnlyBuilder; command: (interaction: ChatInputCommandInteraction) => Promise; }; -export const commands: Command[] = [summarize]; +export const commands: Command[] = [summarize, cowsay];