diff --git a/Document/Message.md b/Document/Message.md
index 81d1fcf..a655c11 100644
--- a/Document/Message.md
+++ b/Document/Message.md
@@ -47,17 +47,6 @@ await message.contextMenu(botID, commandName);
```
-Issue ?
-
-- It has some minor bugs.
-```js
-DiscordAPIError [20012] You are not authorized to perform this action on this application
-Fix it: creating 1 DMs with bot
-In this way, all Slash commands can be obtained
-```
-- With Gateway guild.searchInteraction() (using gateway)
-- With REST: Working ! [TextBasedChannel.sendSlash()].
-
## MessageEmbed ?
- Because Discord has removed the ability to send Embeds in its API, that means MessageEmbed is unusable. But I have created a constructor that uses oEmbed with help [from this site](https://www.reddit.com/r/discordapp/comments/82p8i6/a_basic_tutorial_on_how_to_get_the_most_out_of/)
diff --git a/Document/SlashCommand.md b/Document/SlashCommand.md
index 53f2e86..cd7c993 100644
--- a/Document/SlashCommand.md
+++ b/Document/SlashCommand.md
@@ -1,6 +1,6 @@
# Slash command demo
- Support Autocomplete feature (half)
-- Unused `guild.searchInteraction()` (Use only if not working properly)
+- Unused `guild.searchInteraction()` (Deleted)
# BREAKING CHANGE: Using Slash Command (Sub Command / Sub Group Command) will not accept subCommand argument in args. That means Command Name needs to be changed same as Discord Client
diff --git a/src/client/websocket/handlers/INTERACTION_FAILURE.js b/src/client/websocket/handlers/INTERACTION_FAILURE.js
index 27540b2..1365e3d 100644
--- a/src/client/websocket/handlers/INTERACTION_FAILURE.js
+++ b/src/client/websocket/handlers/INTERACTION_FAILURE.js
@@ -11,6 +11,7 @@ module.exports = (client, { d: data }) => {
client.emit('interactionResponse', {
status: false,
metadata: data,
+ error: 'No response from bot',
});
// Delete cache
client._interactionCache.delete(data.nonce);
diff --git a/src/client/websocket/handlers/INTERACTION_SUCCESS.js b/src/client/websocket/handlers/INTERACTION_SUCCESS.js
index e4dc620..43c0a4c 100644
--- a/src/client/websocket/handlers/INTERACTION_SUCCESS.js
+++ b/src/client/websocket/handlers/INTERACTION_SUCCESS.js
@@ -23,6 +23,7 @@ module.exports = (client, { d: data }) => {
client.emit('interactionResponse', {
status: true,
metadata: data_,
+ error: '',
});
// Delete cache
// client._interactionCache.delete(data.nonce);
diff --git a/src/structures/ApplicationCommand.js b/src/structures/ApplicationCommand.js
index 1257523..8dc3dc1 100644
--- a/src/structures/ApplicationCommand.js
+++ b/src/structures/ApplicationCommand.js
@@ -873,8 +873,15 @@ class ApplicationCommand extends Base {
clearTimeout(timeout);
this.client.removeListener('interactionResponse', handler);
this.client.decrementMaxListeners();
- if (data.status) resolve(data.metadata);
- else reject(data.metadata);
+ if (data.status) {
+ resolve(data.metadata);
+ } else {
+ reject(
+ new Error('INTERACTION_ERROR', {
+ cause: data,
+ }),
+ );
+ }
};
const timeout = setTimeout(() => {
this.client.removeListener('interactionResponse', handler);
@@ -958,8 +965,15 @@ class ApplicationCommand extends Base {
clearTimeout(timeout);
this.client.removeListener('interactionResponse', handler);
this.client.decrementMaxListeners();
- if (data.status) resolve(data.metadata);
- else reject(data.metadata);
+ if (data.status) {
+ resolve(data.metadata);
+ } else {
+ reject(
+ new Error('INTERACTION_ERROR', {
+ cause: data,
+ }),
+ );
+ }
};
const timeout = setTimeout(() => {
this.client.removeListener('interactionResponse', handler);
diff --git a/src/structures/BaseGuildTextChannel.js b/src/structures/BaseGuildTextChannel.js
index 582e65b..3a19550 100644
--- a/src/structures/BaseGuildTextChannel.js
+++ b/src/structures/BaseGuildTextChannel.js
@@ -185,6 +185,7 @@ class BaseGuildTextChannel extends GuildChannel {
setRateLimitPerUser() {}
setNSFW() {}
sendSlash() {}
+ searchInteraction() {}
}
TextBasedChannel.applyToClass(BaseGuildTextChannel, true);
diff --git a/src/structures/DMChannel.js b/src/structures/DMChannel.js
index 9fb18bc..d9b7738 100644
--- a/src/structures/DMChannel.js
+++ b/src/structures/DMChannel.js
@@ -149,6 +149,7 @@ class DMChannel extends Channel {
createMessageComponentCollector() {}
awaitMessageComponent() {}
sendSlash() {}
+ searchInteraction() {}
// Doesn't work on DM channels; bulkDelete() {}
// Doesn't work on DM channels; setRateLimitPerUser() {}
// Doesn't work on DM channels; setNSFW() {}
diff --git a/src/structures/Guild.js b/src/structures/Guild.js
index ceba3dc..4ba7d17 100644
--- a/src/structures/Guild.js
+++ b/src/structures/Guild.js
@@ -1,7 +1,6 @@
'use strict';
const process = require('node:process');
-const setTimeout = require('node:timers').setTimeout;
const { Collection } = require('@discordjs/collection');
const AnonymousGuild = require('./AnonymousGuild');
const GuildAuditLogs = require('./GuildAuditLogs');
@@ -32,12 +31,8 @@ const {
Status,
MFALevels,
PremiumTiers,
- Opcodes,
- Events,
- ApplicationCommandTypes,
} = require('../util/Constants');
const DataResolver = require('../util/DataResolver');
-const SnowflakeUtil = require('../util/SnowflakeUtil');
const SystemChannelFlags = require('../util/SystemChannelFlags');
const Util = require('../util/Util');
@@ -625,67 +620,6 @@ class Guild extends AnonymousGuild {
}
}
- /**
- * Options for guildSearchInteraction
- * @typedef {Object} GuildSearchInteractionOptions
- * @property {string} query Command name
- * @property {?number} [limit=10] Maximum number of results
- * @property {?number} [offset=0] Only return entries for actions made by this user
- * @property {?Snowflake} [botId] BotID
- * @property {?ApplicationCommandType} [type=CHAT_INPUT] Type of command
- */
- /**
- * Searches for guild interactions
- * @param {GuildSearchInteractionOptions} options Options for the search
- * @deprecated
- * @returns {void | Promise}
- */
- searchInteraction(options = {}) {
- let { query, limit, offset, botId, type } = Object.assign(
- { query: undefined, limit: 10, offset: 0, botId: undefined, type: 'CHAT_INPUT' },
- options,
- );
- if (!query) throw new Error('MISSING_VALUE', 'searchInteraction', 'query');
- const nonce = SnowflakeUtil.generate();
- this.shard.send({
- op: Opcodes.REQUEST_APPLICATION_COMMANDS,
- d: {
- guild_id: this.id,
- applications: false,
- limit,
- offset,
- query,
- nonce,
- },
- });
- if (!botId || !type) return undefined;
- return new Promise((resolve, reject) => {
- const handler = applications => {
- timeout.refresh();
- if (applications.nonce !== nonce) return;
- const cmd = applications.application_commands.find(app => app.name == query && app.application_id == botId);
- if (!cmd) return;
- clearTimeout(timeout);
- this.client.removeListener(Events.GUILD_APPLICATION_COMMANDS_UPDATE, handler);
- this.client.decrementMaxListeners();
- resolve(
- this.client.users.cache
- .get(botId)
- ?.application?.commands?.cache?.find(
- c => (c.name === query && c.type == type) || c.type == ApplicationCommandTypes[type],
- ),
- );
- };
- const timeout = setTimeout(() => {
- this.client.removeListener(Events.GUILD_APPLICATION_COMMANDS_UPDATE, handler);
- this.client.decrementMaxListeners();
- reject(new Error('GUILD_APPLICATION_COMMANDS_SEARCH_TIMEOUT'));
- }, 10000).unref();
- this.client.incrementMaxListeners();
- this.client.on(Events.GUILD_APPLICATION_COMMANDS_UPDATE, handler);
- });
- }
-
/**
* Fetches a collection of integrations to this guild.
* Resolves with a collection mapping integrations by their ids.
diff --git a/src/structures/MessageButton.js b/src/structures/MessageButton.js
index 7fa9ff5..bd6da9a 100644
--- a/src/structures/MessageButton.js
+++ b/src/structures/MessageButton.js
@@ -203,8 +203,15 @@ class MessageButton extends BaseMessageComponent {
clearTimeout(timeout);
message.client.removeListener('interactionResponse', handler);
message.client.decrementMaxListeners();
- if (data.status) resolve(data.metadata);
- else reject(data.metadata);
+ if (data.status) {
+ resolve(data.metadata);
+ } else {
+ reject(
+ new Error('INTERACTION_ERROR', {
+ cause: data,
+ }),
+ );
+ }
};
const timeout = setTimeout(() => {
message.client.removeListener('interactionResponse', handler);
diff --git a/src/structures/MessageSelectMenu.js b/src/structures/MessageSelectMenu.js
index 08de0bb..e27685e 100644
--- a/src/structures/MessageSelectMenu.js
+++ b/src/structures/MessageSelectMenu.js
@@ -273,8 +273,15 @@ class MessageSelectMenu extends BaseMessageComponent {
clearTimeout(timeout);
message.client.removeListener('interactionResponse', handler);
message.client.decrementMaxListeners();
- if (data.status) resolve(data.metadata);
- else reject(data.metadata);
+ if (data.status) {
+ resolve(data.metadata);
+ } else {
+ reject(
+ new Error('INTERACTION_ERROR', {
+ cause: data,
+ }),
+ );
+ }
};
const timeout = setTimeout(() => {
message.client.removeListener('interactionResponse', handler);
diff --git a/src/structures/interfaces/TextBasedChannel.js b/src/structures/interfaces/TextBasedChannel.js
index 0be10b1..361f5f1 100644
--- a/src/structures/interfaces/TextBasedChannel.js
+++ b/src/structures/interfaces/TextBasedChannel.js
@@ -407,6 +407,34 @@ class TextBasedChannel {
return this.edit({ nsfw }, reason);
}
+ /**
+ * Search Slash Command (return raw data)
+ * @param {Snowflake} applicationId Application ID
+ * @param {?ApplicationCommandType} type Command Type
+ * @returns {Object}
+ */
+ searchInteraction(applicationId, type = 'CHAT_INPUT') {
+ switch (type) {
+ case 'USER':
+ case 2:
+ type = 2;
+ break;
+ case 'MESSAGE':
+ case 3:
+ type = 3;
+ break;
+ default:
+ type = 1;
+ break;
+ }
+ return this.client.api.channels[this.id]['application-commands'].search.get({
+ query: {
+ type,
+ application_id: applicationId,
+ },
+ });
+ }
+
/**
* Send Slash to this channel
* @param {UserResolvable} bot Bot user
@@ -459,15 +487,7 @@ class TextBasedChannel {
}
if (user._partial) await user.getProfile().catch(() => {});
if (!commandName || typeof commandName !== 'string') throw new Error('Command name is required');
- // Using API to search (without opcode ~ehehe)
- // https://discord.com/api/v9/channels/id/application-commands/search?type=1&application_id=161660517914509312
- const query = {
- type: 1, // Slash commands
- application_id: user.application?.id ?? user.id,
- };
- const data = await this.client.api.channels[this.id]['application-commands'].search.get({
- query,
- });
+ const data = await this.searchInteraction(user.application?.id ?? user.id, 'CHAT_INPUT');
for (const command of data.application_commands) {
if (user.id == command.application_id || user.application.id == command.application_id) {
user.application?.commands?._add(command, true);
@@ -515,6 +535,7 @@ class TextBasedChannel {
'setRateLimitPerUser',
'setNSFW',
'sendSlash',
+ 'searchInteraction',
);
}
for (const prop of props) {
diff --git a/typings/index.d.ts b/typings/index.d.ts
index 4dd50c6..f751e77 100644
--- a/typings/index.d.ts
+++ b/typings/index.d.ts
@@ -1300,7 +1300,6 @@ export class Guild extends AnonymousGuild {
public fetchAuditLogs(
options?: GuildAuditLogsFetchOptions,
): Promise>;
- public searchInteraction(options?: guildSearchInteraction): Promise>;
public fetchIntegrations(): Promise>;
public fetchOwner(options?: BaseFetchOptions): Promise;
public fetchPreview(): Promise;
@@ -4132,6 +4131,10 @@ export interface TextBasedChannelFields extends PartialTextBasedChannelFields {
fetchWebhooks(): Promise>;
sendTyping(): Promise;
sendSlash(bot: UserResolvable, commandName: string, ...args: any): Promise;
+ searchInteraction(
+ applicationId: ApplicationCommandTypes,
+ type?: ApplicationCommandTypes,
+ ): Promise