Skip to content

Commit

Permalink
Handle guild-specific commands
Browse files Browse the repository at this point in the history
  • Loading branch information
D4isDAVID committed Sep 10, 2024
1 parent b9450af commit 1d47233
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 11 deletions.
3 changes: 3 additions & 0 deletions discordbot.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@

# The bot token to use for Discord API authentication.
set discordbot:botToken "YOUR_BOT_TOKEN_HERE"

# The ID of the Discord server to use for server-specific commands.
set discordbot:guildId "YOUR_SERVER_ID_HERE"
7 changes: 7 additions & 0 deletions server/components/core/interaction-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
GatewayDispatchEvents,
InteractionType,
} from '@discordjs/core';
import { guildId } from '../../utils/env.js';
import { interactions, statefuls } from '../loader.js';
import { GatewayEvent } from '../types.js';

Expand Down Expand Up @@ -30,6 +31,12 @@ export const interactionHandler = {
`Command not defined for ${interaction.data.name}.`,
);

if (
command.guildSpecific &&
(!guildId || interaction.guild_id !== guildId)
)
return;

if (
interaction.type === InteractionType.ApplicationCommand &&
(command.data.type ?? ApplicationCommandType.ChatInput) ===
Expand Down
13 changes: 10 additions & 3 deletions server/components/loader.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { Collection } from '@discordjs/collection';
import { RESTPutAPIApplicationCommandsJSONBody } from '@discordjs/core';
import {
RESTPutAPIApplicationCommandsJSONBody,
RESTPutAPIApplicationGuildCommandsJSONBody,
} from '@discordjs/core';
import EventEmitter from 'node:events';
import { inspect } from 'node:util';
import { client, gateway, rest } from '../utils/env.js';
Expand All @@ -21,7 +24,9 @@ export const interactions = {
modals: new Collection<string, Modal>(),
};

export const commands: RESTPutAPIApplicationCommandsJSONBody = [];
export const globalCommands: RESTPutAPIApplicationCommandsJSONBody = [];
export const guildSpecificCommands: RESTPutAPIApplicationGuildCommandsJSONBody =
[];

export const statefuls = {
messageComponents: [],
Expand Down Expand Up @@ -58,7 +63,9 @@ function loadComponent({

componentCommands?.map((command) => {
interactions.commands.set(command.data.name, command);
commands.push(command.data);
(command.guildSpecific ? guildSpecificCommands : globalCommands).push(
command.data,
);
});
messageComponents?.map((messageComponent) => {
const customId = messageComponent.data.custom_id;
Expand Down
3 changes: 3 additions & 0 deletions server/components/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ export type InteractionExecuteArgs<T extends APIInteraction> =

export interface IInteraction<T extends APIInteraction> {
readonly data: InteractionData<T>;
readonly guildSpecific?: T extends APIApplicationCommandInteraction
? boolean
: never;
readonly execute: (props: InteractionExecuteArgs<T>) => Awaitable<void>;
readonly autocomplete?: T extends APIChatInputApplicationCommandInteraction
? (
Expand Down
37 changes: 29 additions & 8 deletions server/index.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,51 @@
import { setTimeout } from 'node:timers/promises';
import { inspect } from 'node:util';
import { commands, loadComponents } from './components/loader.js';
import { api, botToken, gateway } from './utils/env.js';
import {
globalCommands,
guildSpecificCommands,
loadComponents,
} from './components/loader.js';
import { api, botToken, gateway, guildId } from './utils/env.js';

(async () => {
await setTimeout(0);
await setTimeout(0); // avoids console messages possibly conflicting with annoying experimental warning

if (!botToken) {
console.log(
'^1[ERROR] Please provide a bot token with the ^3discordbot:botToken ^1convar and restart the resource.^7',
'^1Please provide a bot token with the ^3discordbot:botToken ^1convar and restart the resource^7',
);
return;
}
if (!guildId) {
console.log(
"^3Server-specific commands won't work because the ^5discordbot:guildId ^3convar wasn't specified^7",
);
}

loadComponents();

const app = await api.oauth2.getCurrentBotApplicationInformation();
RegisterCommand(
'discordbot:deploy',
'discordbot:deployCommands',
async () => {
const result =
const global =
await api.applicationCommands.bulkOverwriteGlobalCommands(
app.id,
commands,
globalCommands,
);
console.log(`Successfully deployed ${result.length} command(s)!`);

let guildSpecific = null;
if (guildId)
guildSpecific =
await api.applicationCommands.bulkOverwriteGuildCommands(
app.id,
guildId,
guildSpecificCommands,
);

console.log(
`Successfully deployed ${global.length} global command(s)${guildSpecific ? ` and ${guildSpecific.length} server-specific command(s)` : ''}!`,
);
},
true,
);
Expand Down
1 change: 1 addition & 0 deletions server/utils/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { REST } from '@discordjs/rest';
import { WebSocketManager } from '@discordjs/ws';

export const botToken = GetConvar('discordbot:botToken', '');
export const guildId = GetConvar('discordbot:guildId', '');

export const rest = new REST({ version: '10' }).setToken(botToken);
export const gateway = new WebSocketManager({
Expand Down

0 comments on commit 1d47233

Please sign in to comment.