Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add automatic command registration

### Changed

- Update dependencies
Expand All @@ -24,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Removed

- **Breaking:** remove `pm2` from the `npm start` script
- Remove `commands:deploy` and `commands:revoke` scripts

### Fixed

Expand Down
12 changes: 1 addition & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ The docker script will take care of every part of the docker development process

### Build the bot

Be sure to install dependencies, generate necessary files, initialize the database, and deploy commands. Here's a handy command to do all of that:
Be sure to install dependencies, generate necessary files, and initialize the database. Here's a handy command to do all of that:

```sh
$ npm run setup
Expand Down Expand Up @@ -245,16 +245,6 @@ Migrations can be run on the database with the following command:
$ npm run db:migrate
```

### Register Slash Commands

If you want support for Discord [Slash Commands](https://support.discord.com/hc/en-us/articles/1500000368501-Slash-Commands-FAQ), you'll need to deploy the commands directly. To avoid rate limits, use a command-line tool, rather than deploying on startup.

Once you have your bot's account token in the .env file, run the following command to tell Discord about our commands:

```sh
$ npm run commands:deploy
```

### Test the bot

Whenever you make changes, you should make sure to run all unit tests before submitting.
Expand Down
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
"type": "module",
"main": "src/main.ts",
"scripts": {
"commands:deploy": "node --env-file=.env . --deploy # TODO: Replace these with automatic command deployment",
"commands:revoke": "node --env-file=.env . --revoke",
"db:generate": "./node_modules/.bin/prisma generate --no-hints --schema ./prisma/schema.prisma",
"db:init": "npm run db:migrate:initial || ./node_modules/.bin/prisma db push && npm run db:migrate:initial",
"db:migrate:initial": "./node_modules/.bin/prisma migrate resolve --applied 20240905171155_initial_state",
Expand All @@ -38,7 +36,7 @@
"lint": "./node_modules/.bin/eslint --flag unstable_native_nodejs_ts_config",
"lint:fix": "npm run lint -- --fix",
"release": "node ./scripts/release.ts",
"setup": "npm ci && npm run export-version && npm run db:migrate && npm run db:generate && npm run commands:deploy",
"setup": "npm ci && npm run export-version && npm run db:migrate && npm run db:generate",
"start": "node --env-file=.env .",
"test": "./node_modules/.bin/vitest",
"type-check": "./node_modules/.bin/tsc --noEmit"
Expand Down
3 changes: 0 additions & 3 deletions scripts/launch_in_docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,5 @@ else
npm run db:init
fi

# Deploy commands
node . --deploy

# Launch
node .
2 changes: 1 addition & 1 deletion src/@types/Command.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ declare global {
| Omit<SlashCommandBuilder, 'addSubcommand' | 'addSubcommandGroup'>;

/** The type of the command. */
type?: ApplicationCommandType.ChatInput;
type: ApplicationCommandType.ChatInput;

/**
* A handler for autocomplete requests.
Expand Down
4 changes: 3 additions & 1 deletion src/commands/contextMenu/altText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { ApplicationCommandType, ContextMenuCommandBuilder } from 'discord.js';
import { isNonEmptyArray } from '../../helpers/guards/isNonEmptyArray.ts';

export const altText: MessageContextMenuCommand = {
info: new ContextMenuCommandBuilder().setName('Get Alt Text'),
info: new ContextMenuCommandBuilder()
.setName('Get Alt Text')
.setType(ApplicationCommandType.Message),
type: ApplicationCommandType.Message,
requiresGuild: false,
async execute({ targetMessage, replyPrivately }) {
Expand Down
4 changes: 3 additions & 1 deletion src/commands/contextMenu/fxtwitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ const x = 'x.com';
const xPermutations = new Set([x, `www.${x}`]);

export const fxtwitter: MessageContextMenuCommand = {
info: new ContextMenuCommandBuilder().setName('Fix Twitter/X Links'),
info: new ContextMenuCommandBuilder()
.setName('Fix Twitter/X Links')
.setType(ApplicationCommandType.Message),
type: ApplicationCommandType.Message,
requiresGuild: false,
async execute({ targetMessage, replyPrivately }) {
Expand Down
4 changes: 3 additions & 1 deletion src/commands/contextMenu/talk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { ApplicationCommandType, ContextMenuCommandBuilder } from 'discord.js';

import { speak } from '../talk.ts';

const builder = new ContextMenuCommandBuilder().setName('Talk');
const builder = new ContextMenuCommandBuilder()
.setName('Talk')
.setType(ApplicationCommandType.Message);

export const talk: MessageContextMenuCommand = {
info: builder,
Expand Down
3 changes: 2 additions & 1 deletion src/commands/emoji.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
import { ApplicationCommandType, EmbedBuilder, SlashCommandBuilder } from 'discord.js';

import { UserMessageError } from '../helpers/UserMessageError.ts';

Expand All @@ -21,6 +21,7 @@ const builder = new SlashCommandBuilder()

export const emoji: GlobalCommand = {
info: builder,
type: ApplicationCommandType.ChatInput,
requiresGuild: false,
async execute({ reply, client, options }): Promise<void> {
const emojiName = options.getString(EmojiName, true);
Expand Down
3 changes: 2 additions & 1 deletion src/commands/findRoom.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { array, boolean, string, tuple, type as schema } from 'superstruct';
import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
import { ApplicationCommandType, EmbedBuilder, SlashCommandBuilder } from 'discord.js';
import { URL } from 'node:url';

import { fetchJson } from '../helpers/fetch.ts';
Expand Down Expand Up @@ -213,6 +213,7 @@ const builder = new SlashCommandBuilder()

export const findRoom: GlobalCommand = {
info: builder,
type: ApplicationCommandType.ChatInput,
requiresGuild: false,
async execute({ replyPrivately, options }): Promise<void> {
const input_bldg = options.getString('building');
Expand Down
3 changes: 2 additions & 1 deletion src/commands/help.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
import { ApplicationCommandType, EmbedBuilder, SlashCommandBuilder } from 'discord.js';

import { appVersion, repo } from '../constants/meta.ts';

Expand All @@ -8,6 +8,7 @@ const builder = new SlashCommandBuilder()

export const help: GlobalCommand = {
info: builder,
type: ApplicationCommandType.ChatInput,
requiresGuild: false,
async execute({ reply }) {
const embed = new EmbedBuilder()
Expand Down
3 changes: 2 additions & 1 deletion src/commands/isCasDown.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EmbedBuilder, SlashCommandBuilder, Colors } from 'discord.js';
import { EmbedBuilder, SlashCommandBuilder, Colors, ApplicationCommandType } from 'discord.js';

const statusURI = 'https://cas.byu.edu/cas/serviceValidate';

Expand All @@ -18,6 +18,7 @@ const builder = new SlashCommandBuilder()

export const isCasDown: GlobalCommand = {
info: builder,
type: ApplicationCommandType.ChatInput,
requiresGuild: false,
async execute({ reply }) {
const res = await fetch(statusURI);
Expand Down
9 changes: 8 additions & 1 deletion src/commands/profile.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type { User } from 'discord.js';
import { DiscordAPIError, EmbedBuilder, SlashCommandBuilder, userMention } from 'discord.js';
import {
ApplicationCommandType,
DiscordAPIError,
EmbedBuilder,
SlashCommandBuilder,
userMention,
} from 'discord.js';

import { DiscordErrorCode } from '../helpers/DiscordErrorCode.ts';

Expand All @@ -14,6 +20,7 @@ const builder = new SlashCommandBuilder()

export const profile: GlobalCommand = {
info: builder,
type: ApplicationCommandType.ChatInput,
requiresGuild: false,
async execute({ client, user, options, reply, guild, source }) {
const otherUser = options.getUser(UserParamName);
Expand Down
3 changes: 2 additions & 1 deletion src/commands/sendtag.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SlashCommandBuilder } from 'discord.js';
import { ApplicationCommandType, SlashCommandBuilder } from 'discord.js';

const NameOption = 'name';

Expand All @@ -15,6 +15,7 @@ const info = new SlashCommandBuilder()

export const sendtag: GuildedCommand = {
info,
type: ApplicationCommandType.ChatInput,
requiresGuild: true,
autocomplete(interaction) {
// Get the user-provided intermediate value
Expand Down
2 changes: 2 additions & 0 deletions src/commands/setReactboard.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
ApplicationCommandType,
Guild,
GuildEmoji,
SlashCommandBuilder,
Expand Down Expand Up @@ -44,6 +45,7 @@ interface ReactboardReactInfo {

export const setReactboard: GuildedCommand = {
info: builder,
type: ApplicationCommandType.ChatInput,
requiresGuild: true,
async execute({ guild, options, replyPrivately }) {
const channel = options.getChannel(channelOption, true);
Expand Down
4 changes: 2 additions & 2 deletions src/commands/stats.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ChatInputCommandInteraction } from 'discord.js';
import { EmbedBuilder, SlashCommandBuilder, userMention } from 'discord.js';
import { ApplicationCommandType, EmbedBuilder, SlashCommandBuilder, userMention } from 'discord.js';

import { db } from '../database/index.ts';
import { sanitize } from '../helpers/sanitize.ts';
Expand Down Expand Up @@ -73,8 +73,8 @@ const builder = new SlashCommandBuilder()

export const stats: GuildedCommand = {
info: builder,
type: ApplicationCommandType.ChatInput,
requiresGuild: true,

async execute({ reply, replyPrivately, interaction, guild }): Promise<void> {
const subcommand = interaction.options.getSubcommand();

Expand Down
8 changes: 7 additions & 1 deletion src/commands/talk.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import type { AttachmentPayload } from 'discord.js';
import { SlashCommandBuilder, ChannelType, PermissionFlagsBits } from 'discord.js';
import {
SlashCommandBuilder,
ChannelType,
PermissionFlagsBits,
ApplicationCommandType,
} from 'discord.js';
import type { AudioResource } from '@discordjs/voice';
import {
createAudioResource,
Expand Down Expand Up @@ -46,6 +51,7 @@ const builder = new SlashCommandBuilder()

export const talk: GlobalCommand = {
info: builder,
type: ApplicationCommandType.ChatInput,
requiresGuild: false,
async execute(context) {
const options = context.options;
Expand Down
3 changes: 2 additions & 1 deletion src/commands/toTheGallows.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SlashCommandBuilder } from 'discord.js';
import { ApplicationCommandType, SlashCommandBuilder } from 'discord.js';

import { EvilHangmanGame } from '../evilHangman/evilHangmanGame.ts';
import { buildEvilHangmanMessage } from '../evilHangman/evilHangmanMessage.ts';
Expand All @@ -25,6 +25,7 @@ const builder = new SlashCommandBuilder()

export const toTheGallows: GlobalCommand = {
info: builder,
type: ApplicationCommandType.ChatInput,
requiresGuild: false,
async execute({ reply, options }): Promise<void> {
const wordLength = options.getInteger(LengthOption);
Expand Down
7 changes: 3 additions & 4 deletions src/commands/xkcd.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
import { ApplicationCommandType, EmbedBuilder, SlashCommandBuilder } from 'discord.js';
import { URL } from 'node:url';
import { number, string, type as schema } from 'superstruct';

Expand Down Expand Up @@ -75,10 +75,9 @@ const builder = new SlashCommandBuilder()
);

export const xkcd: GlobalCommand = {
requiresGuild: false,
info: builder,

// entry point for command execution
type: ApplicationCommandType.ChatInput,
requiresGuild: false,
async execute({ options, reply, sendTyping }) {
let comic = '';
// not making this nullable, instead filling with dummy data to be later filled.
Expand Down
Loading