fix: sendSlash search failure (>25 bot)

This commit is contained in:
March 7th 2022-09-11 09:39:57 +07:00
parent d1382823fe
commit fe1f9911c5
4 changed files with 17 additions and 27 deletions

View File

@ -52,6 +52,7 @@ const Messages = {
EMBED_PROVIDER_NAME: 'MessageEmbed provider name must be a string.', EMBED_PROVIDER_NAME: 'MessageEmbed provider name must be a string.',
INVALID_COMMAND_NAME: allCMD => `Could not parse subGroupCommand and subCommand due to too long: ${allCMD.join(' ')}`, INVALID_COMMAND_NAME: allCMD => `Could not parse subGroupCommand and subCommand due to too long: ${allCMD.join(' ')}`,
INVALID_RANGE_QUERY_MEMBER: 'Invalid range query member. (0<x<=100)', INVALID_RANGE_QUERY_MEMBER: 'Invalid range query member. (0<x<=100)',
MUST_SPECIFY_BOT: 'You must specify a bot to use this command.',
BUTTON_LABEL: 'MessageButton label must be a string', BUTTON_LABEL: 'MessageButton label must be a string',
BUTTON_URL: 'MessageButton URL must be a string', BUTTON_URL: 'MessageButton URL must be a string',

View File

@ -229,12 +229,12 @@ class User extends Base {
} }
if ('premium_type' in data) { if ('premium_type' in data) {
const nitro = NitroType[data.premium_type]; const nitro = NitroType[data.premium_type ?? 0];
/** /**
* Nitro type of the user. * Nitro type of the user.
* @type {NitroType} * @type {NitroType}
*/ */
this.nitroType = nitro ?? `UNKNOWN_${data.premium_type}`; this.nitroType = nitro ?? `UNKNOWN_TYPE_${data.premium_type}`;
} }
if ('guild_member_profile' in data && 'guild_member' in data) { if ('guild_member_profile' in data && 'guild_member' in data) {

View File

@ -402,7 +402,7 @@ class TextBasedChannel {
/** /**
* Send Slash to this channel * Send Slash to this channel
* @param {Snowflake} botId Bot Id (Supports application ID - not bot) * @param {UserResolvable} bot Bot user
* @param {string} commandString Command name (and sub / group formats) * @param {string} commandString Command name (and sub / group formats)
* @param {...?string|string[]} args Command arguments * @param {...?string|string[]} args Command arguments
* @returns {Promise<InteractionResponseBody>} * @returns {Promise<InteractionResponseBody>}
@ -418,7 +418,7 @@ class TextBasedChannel {
* // CommandName is Group Command / Sub Command * // CommandName is Group Command / Sub Command
* channel.sendSlash('123456789012345678', 'embed title', 'description', 'author', '#00ff00') * channel.sendSlash('123456789012345678', 'embed title', 'description', 'author', '#00ff00')
*/ */
async sendSlash(botId, commandString, ...args) { async sendSlash(bot, commandString, ...args) {
args = args.flat(2); args = args.flat(2);
const cmd = commandString.trim().split(' '); const cmd = commandString.trim().split(' ');
// Validate CommandName // Validate CommandName
@ -430,7 +430,8 @@ class TextBasedChannel {
} }
validateName(sub[i]); validateName(sub[i]);
} }
if (!botId) throw new Error('Bot ID is required'); if (!bot) throw new Error('MUST_SPECIFY_BOT');
const botId = this.client.users.resolveId(bot);
// ? maybe ... // ? maybe ...
const user = await this.client.users.fetch(botId).catch(() => {}); const user = await this.client.users.fetch(botId).catch(() => {});
if (!user || !user.bot || !user.application) { if (!user || !user.bot || !user.application) {
@ -439,41 +440,29 @@ class TextBasedChannel {
if (user._partial) await user.getProfile(); if (user._partial) await user.getProfile();
if (!commandName || typeof commandName !== 'string') throw new Error('Command name is required'); if (!commandName || typeof commandName !== 'string') throw new Error('Command name is required');
// Using API to search (without opcode ~ehehe) // Using API to search (without opcode ~ehehe)
let commandTarget; // https://discord.com/api/v9/channels/id/application-commands/search?type=1&application_id=161660517914509312
// https://discord.com/api/v9/channels/id/application-commands/search?type=1&query=aiko&limit=7&include_applications=false&application_id=id
const query = { const query = {
type: 1, // Slash commands type: 1, // Slash commands
include_applications: false, application_id: user.application?.id ?? user.id,
}; };
if (this.client.channels.cache.get(this.id)?.type == 'DM') {
query.application_id = user.application.id;
} else {
query.limit = 25;
query.query = commandName;
}
const data = await this.client.api.channels[this.id]['application-commands'].search.get({ const data = await this.client.api.channels[this.id]['application-commands'].search.get({
query, query,
}); });
for (const command of data.application_commands) { for (const command of data.application_commands) {
if (user.id == command.application_id || user.application.id == command.application_id) { if (user.id == command.application_id || user.application.id == command.application_id) {
const c = user.application?.commands?._add(command, true); user.application?.commands?._add(command, true);
if (command.name == commandName) commandTarget = c;
} else {
const tempUser = this.client.users.cache.get(command.application_id);
if (tempUser && tempUser.bot && tempUser.application) {
tempUser.application?.commands?._add(command, true);
}
} }
} }
// Remove // Remove
commandTarget = const commandTarget = user.application?.commands?.cache.find(
commandTarget || user.application?.commands?.cache.find(c => c.name === commandName && c.type === 'CHAT_INPUT'); c => c.name === commandName && c.type === 'CHAT_INPUT',
);
if (!commandTarget) { if (!commandTarget) {
throw new Error( throw new Error(
'INTERACTION_SEND_FAILURE', 'INTERACTION_SEND_FAILURE',
`SlashCommand ${commandName} is not found (With search)\nDebug:\n+ botId: ${botId}\n+ args: ${args.join( `SlashCommand ${commandName} is not found (With search)\nDebug:\n+ botId: ${botId} (ApplicationId: ${
' | ', user.application?.id
)}`, })\n+ args: ${args.join(' | ') || null}`,
); );
} }
return commandTarget.sendSlashCommand( return commandTarget.sendSlashCommand(

2
typings/index.d.ts vendored
View File

@ -4061,7 +4061,7 @@ export interface TextBasedChannelFields extends PartialTextBasedChannelFields {
setNSFW(nsfw?: boolean, reason?: string): Promise<this>; setNSFW(nsfw?: boolean, reason?: string): Promise<this>;
fetchWebhooks(): Promise<Collection<Snowflake, Webhook>>; fetchWebhooks(): Promise<Collection<Snowflake, Webhook>>;
sendTyping(): Promise<void>; sendTyping(): Promise<void>;
sendSlash(botId: Snowflake, commandName: string, ...args: any): Promise<InteractionResponseBody>; sendSlash(bot: UserResolvable, commandName: string, ...args: any): Promise<InteractionResponseBody>;
} }
export function PartialWebhookMixin<T>(Base?: Constructable<T>): Constructable<T & PartialWebhookFields>; export function PartialWebhookMixin<T>(Base?: Constructable<T>): Constructable<T & PartialWebhookFields>;