Skip to content

Commit

Permalink
fix: only fetch guild ids for commands that require them (#523)
Browse files Browse the repository at this point in the history
* fix: only fetch guild ids for commands that require them

* fix: check for null guilds

* chore: requested change
  • Loading branch information
vladfrangu committed Sep 3, 2022
1 parent 645df81 commit 61f2c07
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 9 deletions.
3 changes: 2 additions & 1 deletion src/lib/structures/Command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ export class Command<PreParseReturn = Args, O extends Command.Options = Command.
// Reset the registry's contents
registry.chatInputCommands.clear();
registry.contextMenuCommands.clear();
registry.guildIdsToFetch.clear();
registry['apiCalls'].length = 0;

// Reload the command
Expand All @@ -292,7 +293,7 @@ export class Command<PreParseReturn = Args, O extends Command.Options = Command.
}

// Re-initialize the store and the API data (insert in the store handles the register method)
const { applicationCommands, globalCommands, guildCommands } = await getNeededRegistryParameters();
const { applicationCommands, globalCommands, guildCommands } = await getNeededRegistryParameters(updatedRegistry.guildIdsToFetch);

// Handle the API calls
// eslint-disable-next-line @typescript-eslint/dot-notation
Expand Down
4 changes: 2 additions & 2 deletions src/lib/structures/CommandStore.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AliasStore } from '@sapphire/pieces';
import { registries } from '../utils/application-commands/ApplicationCommandRegistries';
import { allGuildIdsToFetchCommandsFor, registries } from '../utils/application-commands/ApplicationCommandRegistries';
import { getNeededRegistryParameters } from '../utils/application-commands/getNeededParameters';
import { Command } from './Command';

Expand Down Expand Up @@ -51,7 +51,7 @@ export class CommandStore extends AliasStore<Command> {
// If we don't have an application, that means this was called on login...
if (!this.container.client.application) return;

const { applicationCommands, globalCommands, guildCommands } = await getNeededRegistryParameters();
const { applicationCommands, globalCommands, guildCommands } = await getNeededRegistryParameters(allGuildIdsToFetchCommandsFor);

for (const command of this.values()) {
// eslint-disable-next-line @typescript-eslint/dot-notation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export let defaultBehaviorWhenNotIdentical = RegisterBehavior.Overwrite;

export const registries = new Map<string, ApplicationCommandRegistry>();

export const allGuildIdsToFetchCommandsFor = new Set<string>();

/**
* Acquires a registry for a command by its name.
* @param commandName The name of the command.
Expand Down Expand Up @@ -51,7 +53,7 @@ export async function handleRegistryAPICalls() {
}
}

const { applicationCommands, globalCommands, guildCommands } = await getNeededRegistryParameters();
const { applicationCommands, globalCommands, guildCommands } = await getNeededRegistryParameters(allGuildIdsToFetchCommandsFor);

for (const registry of registries.values()) {
// eslint-disable-next-line @typescript-eslint/dot-notation
Expand Down
18 changes: 17 additions & 1 deletion src/lib/utils/application-commands/ApplicationCommandRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
SlashCommandSubcommandsOnlyBuilder
} from '@discordjs/builders';
import { container } from '@sapphire/pieces';
import { isNullishOrEmpty } from '@sapphire/utilities';
import {
ApplicationCommandType,
RESTPostAPIChatInputApplicationCommandsJSONBody,
Expand All @@ -20,7 +21,7 @@ import type {
UserApplicationCommandData
} from 'discord.js';
import { InternalRegistryAPIType, RegisterBehavior } from '../../types/Enums';
import { getDefaultBehaviorWhenNotIdentical } from './ApplicationCommandRegistries';
import { allGuildIdsToFetchCommandsFor, getDefaultBehaviorWhenNotIdentical } from './ApplicationCommandRegistries';
import { CommandDifference, getCommandDifferences, getCommandDifferencesFast } from './computeDifferences';
import { convertApplicationCommandToApiData, normalizeChatInputCommand, normalizeContextMenuCommand } from './normalizeInputs';

Expand All @@ -29,6 +30,7 @@ export class ApplicationCommandRegistry {

public readonly chatInputCommands = new Set<string>();
public readonly contextMenuCommands = new Set<string>();
public readonly guildIdsToFetch = new Set<string>();

private readonly apiCalls: InternalAPICall[] = [];

Expand Down Expand Up @@ -66,6 +68,13 @@ export class ApplicationCommandRegistry {
}
}

if (!isNullishOrEmpty(options?.guildIds)) {
for (const id of options!.guildIds) {
this.guildIdsToFetch.add(id);
allGuildIdsToFetchCommandsFor.add(id);
}
}

return this;
}

Expand Down Expand Up @@ -93,6 +102,13 @@ export class ApplicationCommandRegistry {
}
}

if (!isNullishOrEmpty(options?.guildIds)) {
for (const id of options!.guildIds) {
this.guildIdsToFetch.add(id);
allGuildIdsToFetchCommandsFor.add(id);
}
}

return this;
}

Expand Down
9 changes: 5 additions & 4 deletions src/lib/utils/application-commands/getNeededParameters.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { container } from '@sapphire/pieces';
import type { ApplicationCommand, ApplicationCommandManager, Collection } from 'discord.js';

export async function getNeededRegistryParameters() {
export async function getNeededRegistryParameters(guildIds: Set<string> = new Set()) {
const { client } = container;

const applicationCommands = client.application!.commands;
const globalCommands = await applicationCommands.fetch({ withLocalizations: true });
const guildCommands = await fetchGuildCommands(applicationCommands);
const guildCommands = await fetchGuildCommands(applicationCommands, guildIds);

return {
applicationCommands,
Expand All @@ -15,10 +15,10 @@ export async function getNeededRegistryParameters() {
};
}

async function fetchGuildCommands(commands: ApplicationCommandManager) {
async function fetchGuildCommands(commands: ApplicationCommandManager, guildIds: Set<string>) {
const map = new Map<string, Collection<string, ApplicationCommand>>();

for (const [guildId, guild] of commands.client.guilds.cache.entries()) {
for (const guildId of guildIds) {
try {
const guildCommands = await commands.fetch({ guildId, withLocalizations: true });
map.set(guildId, guildCommands);
Expand All @@ -28,6 +28,7 @@ async function fetchGuildCommands(commands: ApplicationCommandManager) {
if (preventFailedToFetchLogForGuilds === true) continue;

if (Array.isArray(preventFailedToFetchLogForGuilds) && !preventFailedToFetchLogForGuilds?.includes(guildId)) {
const guild = container.client.guilds.resolve(guildId) ?? { name: 'Guild not in cache' };
container.logger.warn(
`ApplicationCommandRegistries: Failed to fetch guild commands for guild "${guild.name}" (${guildId}).`,
'Make sure to authorize your application with the "applications.commands" scope in that guild.'
Expand Down

0 comments on commit 61f2c07

Please sign in to comment.