|
| 1 | +import { CommandInteraction } from "discord.js"; |
| 2 | +import { |
| 3 | + SlashCommandBuilder, |
| 4 | + blockQuote, |
| 5 | + bold, |
| 6 | + codeBlock, |
| 7 | + inlineCode, |
| 8 | + italic, |
| 9 | + quote, |
| 10 | + spoiler, |
| 11 | + strikethrough, |
| 12 | + underscore, |
| 13 | +} from "@discordjs/builders"; |
| 14 | + |
| 15 | +const formats: { [k: string]: (s: string) => string } = { |
| 16 | + blockQuote, |
| 17 | + bold, |
| 18 | + codeBlock, |
| 19 | + inlineCode, |
| 20 | + italic, |
| 21 | + quote, |
| 22 | + spoiler, |
| 23 | + strikethrough, |
| 24 | + underscore, |
| 25 | +}; |
| 26 | + |
| 27 | +export const data = new SlashCommandBuilder() |
| 28 | + .setName("echo") |
| 29 | + .setDescription("Replies with your input, optionally formatted") |
| 30 | + .addStringOption((option) => |
| 31 | + option.setName("input").setDescription("The input to echo back").setRequired(true) |
| 32 | + ) |
| 33 | + .addStringOption((option) => |
| 34 | + option |
| 35 | + .setName("format") |
| 36 | + .setDescription("The format to use") |
| 37 | + .addChoices(Object.keys(formats).map((k) => [k, k])) |
| 38 | + ) |
| 39 | + .toJSON(); |
| 40 | + |
| 41 | +export const call = async (interaction: CommandInteraction) => { |
| 42 | + const input = interaction.options.getString("input", true); |
| 43 | + const format = interaction.options.getString("format"); |
| 44 | + const msg = format && formats.hasOwnProperty(format) ? formats[format](input) : input; |
| 45 | + await interaction.reply(msg); |
| 46 | +}; |
| 47 | + |
| 48 | +/* |
| 49 | +// It's annoying having to repeat options name/type in `data` and `call`. |
| 50 | +// Maybe it's possible to define `options` in `data` with `zod`? |
| 51 | +// Registering should work as long as we can produce an object matching |
| 52 | +// `RESTPostAPIApplicationCommandsJSONBody`. |
| 53 | +const data = new SlashCommandBuilder() |
| 54 | + .setName("echo") |
| 55 | + .setDescription("Replies with your input") |
| 56 | + .addStringOption((option) => |
| 57 | + option.setName("input").setDescription("The input to echo back").setRequired(true) |
| 58 | + ) |
| 59 | + .toJSON(); |
| 60 | +// is equivalent to |
| 61 | +const data = { |
| 62 | + name: "echo", |
| 63 | + description: "Replies with your input", |
| 64 | + options: [ |
| 65 | + { |
| 66 | + // ApplicationCommandOptionType.String |
| 67 | + type: 3, |
| 68 | + name: "input", |
| 69 | + description: "The input to echo back", |
| 70 | + required: true, |
| 71 | + }, |
| 72 | + ], |
| 73 | +}; |
| 74 | +// will be nice to use zod to define options, so we can extract in `call`. |
| 75 | +const Options = z.preprocess( |
| 76 | + // preprocess `interaction.options.data` array into an object |
| 77 | + preprocessor, |
| 78 | + // schema |
| 79 | + z.object({ |
| 80 | + input: z.string().nonempty().describe("The input to echo back"), |
| 81 | + }) |
| 82 | +); |
| 83 | +const data = { |
| 84 | + name: "echo", |
| 85 | + description: "Replies with your input", |
| 86 | + options: toDiscordOptions(Options), |
| 87 | +}; |
| 88 | +// so we can get typed options |
| 89 | +// const { input } = Options.parse(interaction.options.data); |
| 90 | +*/ |
0 commit comments