From 5fd9696be54482ed6cf3a6296fbbdcee61a1dee9 Mon Sep 17 00:00:00 2001 From: UnbraveChimp Date: Mon, 4 May 2026 05:09:22 +0200 Subject: [PATCH 1/4] fix: only expose setupTicket to admins --- src/commands/utility/setupTicket.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/commands/utility/setupTicket.ts b/src/commands/utility/setupTicket.ts index 203704a..54896ef 100644 --- a/src/commands/utility/setupTicket.ts +++ b/src/commands/utility/setupTicket.ts @@ -4,7 +4,8 @@ import { ButtonBuilder, ButtonStyle, ChannelType, - MessageFlags + MessageFlags, + PermissionFlagsBits } from 'discord.js'; export class SetupTicketCommand extends Command { @@ -17,6 +18,7 @@ export class SetupTicketCommand extends Command { builder .setName('setup-ticket') .setDescription('Post the ticket panel in a channel.') + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .addChannelOption((option) => option .setName('channel') From 9bf94cd85299756beb0b7d87deccd8f4157db587 Mon Sep 17 00:00:00 2001 From: UnbraveChimp Date: Mon, 4 May 2026 05:15:28 +0200 Subject: [PATCH 2/4] docker: remove stale deploy at end --- Dockerfile | 2 +- README.md | 5 ++--- package.json | 2 +- src/commands/utility/setupTicket.ts | 5 +++-- src/interaction-handlers/ticket/createTicketHandler.ts | 7 ++++--- src/interaction-handlers/ticket/removeTicketHandler.ts | 7 ++++--- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Dockerfile b/Dockerfile index f74b144..9533cf2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,4 +22,4 @@ RUN pnpm install --prod --frozen-lockfile COPY --from=builder /app/dist ./dist -CMD ["sh", "-c", "pnpm prisma db push && pnpm run deploy && pnpm start"] +CMD ["sh", "-c", "pnpm prisma db push && pnpm start"] diff --git a/README.md b/README.md index a55c31e..5c17bf5 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,8 @@ An opensource modern Discord Bot built for moderation, utilities and support! 4. Install dependencies with `pnpm install` 5. Generate prisma using `pnpm prisma generate` 6. Update your local databse using `pnpm prisma db push` -7. Deploy the commands with `pnpm run deploy` -8. Run the development server with `pnpm dev` -9. The bot is now live on Discord with registered commands! +7. Run the development server with `pnpm dev` +8. The bot will register commands automatically on startup. > [!IMPORTANT] > When testing, add the precondition, 'DevMode' and set 'DEV' to true in your env. diff --git a/package.json b/package.json index e046186..e322299 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "build": "rimraf dist && prisma generate && tsc", "lint": "prettier --check . && eslint --ext .ts --format=pretty src", - "deploy": "node --env-file-if-exists=.env dist/util/deploy.js", + "deploy": "node -e \"console.log('Slash commands are registered automatically on startup via Sapphire.')\"", "format": "prettier --write . && eslint --ext .ts --fix --format=pretty src", "predev": "pnpm build", "start": "node --env-file-if-exists=.env dist/index.js", diff --git a/src/commands/utility/setupTicket.ts b/src/commands/utility/setupTicket.ts index 54896ef..4b58a30 100644 --- a/src/commands/utility/setupTicket.ts +++ b/src/commands/utility/setupTicket.ts @@ -1,4 +1,5 @@ import { Command } from '@sapphire/framework'; +import { emojis } from '#utils/emoji.js'; import { ActionRowBuilder, ButtonBuilder, @@ -40,12 +41,12 @@ export class SetupTicketCommand extends Command { const row = new ActionRowBuilder().addComponents(button); await channel.send({ - content: '**Create a ticket by clicking the button below!**', + content: `**Create a ticket by clicking the button below!**`, components: [row] }); await interaction.reply({ - content: `Ticket panel sent in ${channel}.`, + content: `${emojis.rightArrow2} Ticket panel sent in ${channel}.`, flags: MessageFlags.Ephemeral }); } diff --git a/src/interaction-handlers/ticket/createTicketHandler.ts b/src/interaction-handlers/ticket/createTicketHandler.ts index e98f9d3..893f423 100644 --- a/src/interaction-handlers/ticket/createTicketHandler.ts +++ b/src/interaction-handlers/ticket/createTicketHandler.ts @@ -11,6 +11,7 @@ import { } from 'discord.js'; import { TextInputBuilder, TextInputStyle, type ButtonInteraction } from 'discord.js'; import { getSettings, updateSettings } from '#lib/settings.js'; +import { emojis } from '#utils/emoji.js'; export class ButtonHandler extends InteractionHandler { public constructor(ctx: InteractionHandler.LoaderContext, options: InteractionHandler.Options) { @@ -29,7 +30,7 @@ export class ButtonHandler extends InteractionHandler { public async run(interaction: ButtonInteraction) { if (!interaction.inGuild()) { await interaction.reply({ - content: 'This button can only be used in a server.', + content: `${emojis.rightArrow2} This button can only be used in a server.`, flags: MessageFlags.Ephemeral }); return; @@ -37,7 +38,7 @@ export class ButtonHandler extends InteractionHandler { if (!interaction.guild) { await interaction.reply({ - content: 'Failed to create ticket.', + content: `${emojis.rightArrow2} Failed to create ticket.`, flags: MessageFlags.Ephemeral }); return; @@ -113,7 +114,7 @@ export class ButtonHandler extends InteractionHandler { }); await modalSubmit.reply({ - content: 'Created a ticket!', + content: `${emojis.rightArrow2} Created a ticket!`, flags: MessageFlags.Ephemeral }); diff --git a/src/interaction-handlers/ticket/removeTicketHandler.ts b/src/interaction-handlers/ticket/removeTicketHandler.ts index 24ca394..09cc843 100644 --- a/src/interaction-handlers/ticket/removeTicketHandler.ts +++ b/src/interaction-handlers/ticket/removeTicketHandler.ts @@ -1,6 +1,7 @@ import { InteractionHandler, InteractionHandlerTypes } from '@sapphire/framework'; import { MessageFlags } from 'discord.js'; import type { ButtonInteraction } from 'discord.js'; +import { emojis } from '#utils/emoji.js'; export class ButtonHandler extends InteractionHandler { public constructor(ctx: InteractionHandler.LoaderContext, options: InteractionHandler.Options) { @@ -19,7 +20,7 @@ export class ButtonHandler extends InteractionHandler { public async run(interaction: ButtonInteraction) { if (!interaction.inGuild()) { await interaction.reply({ - content: 'This button can only be used in a server.', + content: `${emojis.rightArrow2} This button can only be used in a server.`, flags: MessageFlags.Ephemeral }); return; @@ -27,7 +28,7 @@ export class ButtonHandler extends InteractionHandler { if (!interaction.guild) { await interaction.reply({ - content: 'Failed to remove ticket.', + content: `${emojis.rightArrow2} Failed to remove ticket.`, flags: MessageFlags.Ephemeral }); return; @@ -37,7 +38,7 @@ export class ButtonHandler extends InteractionHandler { if (!channel || !('deletable' in channel) || !channel.deletable) { await interaction.reply({ - content: 'I cannot delete this channel.', + content: `${emojis.rightArrow2} I cannot delete this channel.`, flags: MessageFlags.Ephemeral }); return; From 66a7daa5bdfbe6aece73ec69c66519d4fe5988ca Mon Sep 17 00:00:00 2001 From: UnbraveChimp Date: Mon, 4 May 2026 05:21:58 +0200 Subject: [PATCH 3/4] chore: improve build to catch bug --- .github/workflows/build.yaml | 12 +++++++++++- package.json | 1 - 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index c3d9663..1a4d151 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,6 +1,7 @@ name: Build Test on: push: + pull_request: permissions: contents: read @@ -23,6 +24,15 @@ jobs: node-version: ${{ matrix.node-version }} cache: "pnpm" - name: Install dependencies - run: pnpm install + run: pnpm install --frozen-lockfile - name: Build run: pnpm build + - name: Build production image + run: docker build -t quest-bot:test . + - name: Smoke test production image + run: > + docker run --rm --entrypoint sh quest-bot:test -c + "set -e; + pnpm run deploy; + test -f /app/dist/index.js; + node --check /app/dist/index.js" diff --git a/package.json b/package.json index e322299..65c6837 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ "scripts": { "build": "rimraf dist && prisma generate && tsc", "lint": "prettier --check . && eslint --ext .ts --format=pretty src", - "deploy": "node -e \"console.log('Slash commands are registered automatically on startup via Sapphire.')\"", "format": "prettier --write . && eslint --ext .ts --fix --format=pretty src", "predev": "pnpm build", "start": "node --env-file-if-exists=.env dist/index.js", From ffe859f4e441599e9a6bc5c5d1ed4eca3ce2d37c Mon Sep 17 00:00:00 2001 From: UnbraveChimp Date: Mon, 4 May 2026 05:25:03 +0200 Subject: [PATCH 4/4] chore: fix --- .github/workflows/build.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 1a4d151..d192c1b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -29,10 +29,9 @@ jobs: run: pnpm build - name: Build production image run: docker build -t quest-bot:test . - - name: Smoke test production image + - name: Test production image run: > docker run --rm --entrypoint sh quest-bot:test -c "set -e; - pnpm run deploy; test -f /app/dist/index.js; node --check /app/dist/index.js"