Slash Command and Context Menu
- Doc. comming soon
This commit is contained in:
		@@ -155,10 +155,11 @@ const Messages = {
 | 
			
		||||
  SWEEP_FILTER_RETURN: 'The return value of the sweepFilter function was not false or a Function',
 | 
			
		||||
 | 
			
		||||
  INVALID_BOT_METHOD: `Bot accounts cannot use this method`,
 | 
			
		||||
	INVALID_USER_METHOD: `User accounts cannot use this method`,
 | 
			
		||||
	INVALID_LOCALE: 'Unable to select this location',
 | 
			
		||||
	FOLDER_NOT_FOUND: 'Server directory not found',
 | 
			
		||||
	FOLDER_POSITION_INVALID: 'The server index in the directory is invalid',
 | 
			
		||||
  INVALID_USER_METHOD: `User accounts cannot use this method`,
 | 
			
		||||
  INVALID_LOCALE: 'Unable to select this location',
 | 
			
		||||
  FOLDER_NOT_FOUND: 'Server directory not found',
 | 
			
		||||
  FOLDER_POSITION_INVALID: 'The server index in the directory is invalid',
 | 
			
		||||
  APPLICATION_ID_INVALID: 'The application isn\'t BOT',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
for (const [name, message] of Object.entries(Messages)) register(name, message);
 | 
			
		||||
 
 | 
			
		||||
@@ -12,14 +12,15 @@ const { ApplicationCommandTypes } = require('../util/Constants');
 | 
			
		||||
 * @extends {CachedManager}
 | 
			
		||||
 */
 | 
			
		||||
class ApplicationCommandManager extends CachedManager {
 | 
			
		||||
  constructor(client, iterable) {
 | 
			
		||||
  constructor(client, iterable, user) {
 | 
			
		||||
    super(client, ApplicationCommand, iterable);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The manager for permissions of arbitrary commands on arbitrary guilds
 | 
			
		||||
     * @type {ApplicationCommandPermissionsManager}
 | 
			
		||||
     */
 | 
			
		||||
    this.permissions = new ApplicationCommandPermissionsManager(this);
 | 
			
		||||
    this.permissions = new ApplicationCommandPermissionsManager(this, user);
 | 
			
		||||
    this.user = user;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@@ -41,7 +42,7 @@ class ApplicationCommandManager extends CachedManager {
 | 
			
		||||
   * @private
 | 
			
		||||
   */
 | 
			
		||||
  commandPath({ id, guildId } = {}) {
 | 
			
		||||
    let path = this.client.api.applications(this.client.application.id);
 | 
			
		||||
    let path = this.client.api.applications(this.user.id);
 | 
			
		||||
    if (this.guild ?? guildId) path = path.guilds(this.guild?.id ?? guildId);
 | 
			
		||||
    return id ? path.commands(id) : path.commands;
 | 
			
		||||
  }
 | 
			
		||||
@@ -114,6 +115,7 @@ class ApplicationCommandManager extends CachedManager {
 | 
			
		||||
   *   .catch(console.error);
 | 
			
		||||
   */
 | 
			
		||||
  async create(command, guildId) {
 | 
			
		||||
    if(!this.client.user.bot) throw new Error("INVALID_USER_METHOD");
 | 
			
		||||
    const data = await this.commandPath({ guildId }).post({
 | 
			
		||||
      data: this.constructor.transformCommand(command),
 | 
			
		||||
    });
 | 
			
		||||
@@ -143,6 +145,7 @@ class ApplicationCommandManager extends CachedManager {
 | 
			
		||||
   *   .catch(console.error);
 | 
			
		||||
   */
 | 
			
		||||
  async set(commands, guildId) {
 | 
			
		||||
    if(!this.client.user.bot) throw new Error("INVALID_USER_METHOD");
 | 
			
		||||
    const data = await this.commandPath({ guildId }).put({
 | 
			
		||||
      data: commands.map(c => this.constructor.transformCommand(c)),
 | 
			
		||||
    });
 | 
			
		||||
@@ -165,6 +168,7 @@ class ApplicationCommandManager extends CachedManager {
 | 
			
		||||
   *   .catch(console.error);
 | 
			
		||||
   */
 | 
			
		||||
  async edit(command, data, guildId) {
 | 
			
		||||
    if(!this.client.user.bot) throw new Error("INVALID_USER_METHOD");
 | 
			
		||||
    const id = this.resolveId(command);
 | 
			
		||||
    if (!id) throw new TypeError('INVALID_TYPE', 'command', 'ApplicationCommandResolvable');
 | 
			
		||||
 | 
			
		||||
@@ -187,6 +191,7 @@ class ApplicationCommandManager extends CachedManager {
 | 
			
		||||
   *   .catch(console.error);
 | 
			
		||||
   */
 | 
			
		||||
  async delete(command, guildId) {
 | 
			
		||||
    if(!this.client.user.bot) throw new Error("INVALID_USER_METHOD");
 | 
			
		||||
    const id = this.resolveId(command);
 | 
			
		||||
    if (!id) throw new TypeError('INVALID_TYPE', 'command', 'ApplicationCommandResolvable');
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ const { ApplicationCommandPermissionTypes, APIErrors } = require('../util/Consta
 | 
			
		||||
 * @extends {BaseManager}
 | 
			
		||||
 */
 | 
			
		||||
class ApplicationCommandPermissionsManager extends BaseManager {
 | 
			
		||||
  constructor(manager) {
 | 
			
		||||
  constructor(manager, user) {
 | 
			
		||||
    super(manager.client);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -37,6 +37,8 @@ class ApplicationCommandPermissionsManager extends BaseManager {
 | 
			
		||||
     * @type {?Snowflake}
 | 
			
		||||
     */
 | 
			
		||||
    this.commandId = manager.id ?? null;
 | 
			
		||||
 | 
			
		||||
    this.user = user;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@@ -47,7 +49,7 @@ class ApplicationCommandPermissionsManager extends BaseManager {
 | 
			
		||||
   * @private
 | 
			
		||||
   */
 | 
			
		||||
  permissionsPath(guildId, commandId) {
 | 
			
		||||
    return this.client.api.applications(this.client.application.id).guilds(guildId).commands(commandId).permissions;
 | 
			
		||||
    return this.client.api.applications(this.user.id).guilds(guildId).commands(commandId).permissions;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@@ -159,6 +161,7 @@ class ApplicationCommandPermissionsManager extends BaseManager {
 | 
			
		||||
   *   .catch(console.error);
 | 
			
		||||
   */
 | 
			
		||||
  async set({ guild, command, permissions, fullPermissions } = {}) {
 | 
			
		||||
    if(!this.manager.client.user.bot) throw new Error("INVALID_USER_METHOD");
 | 
			
		||||
    const { guildId, commandId } = this._validateOptions(guild, command);
 | 
			
		||||
 | 
			
		||||
    if (commandId) {
 | 
			
		||||
@@ -220,6 +223,7 @@ class ApplicationCommandPermissionsManager extends BaseManager {
 | 
			
		||||
   *   .catch(console.error);
 | 
			
		||||
   */
 | 
			
		||||
  async add({ guild, command, permissions }) {
 | 
			
		||||
    if(!this.manager.client.user.bot) throw new Error("INVALID_USER_METHOD");
 | 
			
		||||
    const { guildId, commandId } = this._validateOptions(guild, command);
 | 
			
		||||
    if (!commandId) throw new TypeError('INVALID_TYPE', 'command', 'ApplicationCommandResolvable');
 | 
			
		||||
    if (!Array.isArray(permissions)) {
 | 
			
		||||
@@ -271,6 +275,7 @@ class ApplicationCommandPermissionsManager extends BaseManager {
 | 
			
		||||
   *    .catch(console.error);
 | 
			
		||||
   */
 | 
			
		||||
  async remove({ guild, command, users, roles }) {
 | 
			
		||||
    if(!this.manager.client.user.bot) throw new Error("INVALID_USER_METHOD");
 | 
			
		||||
    const { guildId, commandId } = this._validateOptions(guild, command);
 | 
			
		||||
    if (!commandId) throw new TypeError('INVALID_TYPE', 'command', 'ApplicationCommandResolvable');
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ const Base = require('./Base');
 | 
			
		||||
const ApplicationCommandPermissionsManager = require('../managers/ApplicationCommandPermissionsManager');
 | 
			
		||||
const { ApplicationCommandOptionTypes, ApplicationCommandTypes, ChannelTypes } = require('../util/Constants');
 | 
			
		||||
const SnowflakeUtil = require('../util/SnowflakeUtil');
 | 
			
		||||
const { Message } = require('..');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents an application command.
 | 
			
		||||
@@ -42,7 +43,7 @@ class ApplicationCommand extends Base {
 | 
			
		||||
     * The manager for permissions of this command on its guild or arbitrary guilds when the command is global
 | 
			
		||||
     * @type {ApplicationCommandPermissionsManager}
 | 
			
		||||
     */
 | 
			
		||||
    this.permissions = new ApplicationCommandPermissionsManager(this);
 | 
			
		||||
    this.permissions = new ApplicationCommandPermissionsManager(this, user);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The type of this application command
 | 
			
		||||
@@ -50,6 +51,8 @@ class ApplicationCommand extends Base {
 | 
			
		||||
     */
 | 
			
		||||
    this.type = ApplicationCommandTypes[data.type];
 | 
			
		||||
 | 
			
		||||
    this.user = client.users.cache.get(this.applicationId);
 | 
			
		||||
 | 
			
		||||
    this._patch(data);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -392,6 +395,87 @@ class ApplicationCommand extends Base {
 | 
			
		||||
      [maxValueKey]: option.maxValue ?? option.max_value,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * Send Slash command to channel
 | 
			
		||||
   * @param {Message} message Discord Message
 | 
			
		||||
   * @param {Array<string>} options The options to Slash Command
 | 
			
		||||
   * @returns {Promise<Boolean>}
 | 
			
		||||
   * @example
 | 
			
		||||
   * const botID = '12345678987654321'
 | 
			
		||||
   * const user = await client.users.fetch(botID);
 | 
			
		||||
   * const application = await user.applications.fetch();
 | 
			
		||||
   * const command = application.commands.first();
 | 
			
		||||
   * await command.sendSlashCommand(messsage, ['option1', 'option2']);
 | 
			
		||||
   */
 | 
			
		||||
  async sendSlashCommand(message, options = []) {
 | 
			
		||||
    // Check Options
 | 
			
		||||
    if (!message instanceof Message) throw new TypeError('The message must be a Discord.Message');
 | 
			
		||||
    if (!Array.isArray(options)) throw new TypeError('The options must be an array of strings');
 | 
			
		||||
    if (this.type !== 'CHAT_INPUT') return false;
 | 
			
		||||
    const optionFormat = [];
 | 
			
		||||
    let i = 0;
 | 
			
		||||
    for (i; i < options.length ; i++) {
 | 
			
		||||
      const value = options[i];
 | 
			
		||||
      if (typeof value !== 'string') {
 | 
			
		||||
        throw new TypeError(`Expected option to be a String, got ${typeof value}`);
 | 
			
		||||
      }
 | 
			
		||||
      if (!this.options[i]) continue;
 | 
			
		||||
      const data = {
 | 
			
		||||
        type: ApplicationCommandOptionTypes[this.options[i].type],
 | 
			
		||||
        name: this.options[i].name,
 | 
			
		||||
        value: value,
 | 
			
		||||
      }
 | 
			
		||||
      optionFormat.push(data);
 | 
			
		||||
    }
 | 
			
		||||
    if (this.options[i]?.required) throw new Error('Value required missing');
 | 
			
		||||
    await this.client.api.interactions.post({ body: {
 | 
			
		||||
				type: 2, // ???
 | 
			
		||||
				application_id: this.applicationId,
 | 
			
		||||
				guild_id: message.guildId,
 | 
			
		||||
				channel_id: message.channelId,
 | 
			
		||||
				session_id: this.client.session_id,
 | 
			
		||||
				data: {
 | 
			
		||||
          // ApplicationCommandData
 | 
			
		||||
					version: this.version,
 | 
			
		||||
					id: this.id,
 | 
			
		||||
					name: this.name,
 | 
			
		||||
					type: ApplicationCommandTypes[this.type],
 | 
			
		||||
					options: optionFormat,
 | 
			
		||||
				},
 | 
			
		||||
			}})
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * Message Context Menu
 | 
			
		||||
   * @param {Message} message Discord Message
 | 
			
		||||
   * @returns {Promise<Boolean>}
 | 
			
		||||
   * @example
 | 
			
		||||
   * const botID = '12345678987654321'
 | 
			
		||||
   * const user = await client.users.fetch(botID);
 | 
			
		||||
   * const application = await user.applications.fetch();
 | 
			
		||||
   * const command = application.commands.first();
 | 
			
		||||
   * await command.sendContextMenu(messsage);
 | 
			
		||||
   */
 | 
			
		||||
  async sendContextMenu(message) {
 | 
			
		||||
    if (!message instanceof Message) throw new TypeError('The message must be a Discord.Message');
 | 
			
		||||
    if (this.type == 'CHAT_INPUT') return false;
 | 
			
		||||
    await this.client.api.interactions.post({ body: {
 | 
			
		||||
				type: 2, // ???
 | 
			
		||||
				application_id: this.applicationId,
 | 
			
		||||
				guild_id: message.guildId,
 | 
			
		||||
				channel_id: message.channelId,
 | 
			
		||||
				session_id: this.client.session_id,
 | 
			
		||||
				data: {
 | 
			
		||||
          // ApplicationCommandData
 | 
			
		||||
					version: this.version,
 | 
			
		||||
					id: this.id,
 | 
			
		||||
					name: this.name,
 | 
			
		||||
					type: ApplicationCommandTypes[this.type],
 | 
			
		||||
          target_id: ApplicationCommandTypes[this.type] == 1 ? message.author.id : message.id,
 | 
			
		||||
				},
 | 
			
		||||
			}})
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = ApplicationCommand;
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ class ClientApplication extends Application {
 | 
			
		||||
     * The application command manager for this application
 | 
			
		||||
     * @type {ApplicationCommandManager}
 | 
			
		||||
     */
 | 
			
		||||
    this.commands = new ApplicationCommandManager(this.client);
 | 
			
		||||
    this.commands = null // Selfbot
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _patch(data) {
 | 
			
		||||
@@ -97,7 +97,7 @@ class ClientApplication extends Application {
 | 
			
		||||
   * @returns {Promise<ClientApplication>}
 | 
			
		||||
   */
 | 
			
		||||
  async fetch() {
 | 
			
		||||
    if(!this.client.bot) throw new Error("INVALID_USER_METHOD");
 | 
			
		||||
    if(!this.client.user.bot) throw new Error("INVALID_USER_METHOD");
 | 
			
		||||
    const app = await this.client.api.oauth2.applications('@me').get();
 | 
			
		||||
    this._patch(app);
 | 
			
		||||
    return this;
 | 
			
		||||
 
 | 
			
		||||
@@ -57,12 +57,6 @@ class Guild extends AnonymousGuild {
 | 
			
		||||
  constructor(client, data) {
 | 
			
		||||
    super(client, data, false);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A manager of the application commands belonging to this guild
 | 
			
		||||
     * @type {GuildApplicationCommandManager}
 | 
			
		||||
     */
 | 
			
		||||
    this.commands = new GuildApplicationCommandManager(this);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A manager of the members belonging to this guild
 | 
			
		||||
     * @type {GuildMemberManager}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ const { Error } = require('../errors');
 | 
			
		||||
const SnowflakeUtil = require('../util/SnowflakeUtil');
 | 
			
		||||
const UserFlags = require('../util/UserFlags');
 | 
			
		||||
const { default: Collection } = require('@discordjs/collection');
 | 
			
		||||
const ApplicationCommandManager = require('../managers/ApplicationCommandManager');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents a user on Discord.
 | 
			
		||||
@@ -37,7 +38,7 @@ class User extends Base {
 | 
			
		||||
		this.premiumSince = null;
 | 
			
		||||
		this.premiumGuildSince = null;
 | 
			
		||||
		this.mutualGuilds = new Collection();
 | 
			
		||||
 | 
			
		||||
    this.applications = null;
 | 
			
		||||
    this._patch(data);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -58,6 +59,9 @@ class User extends Base {
 | 
			
		||||
       * @type {?boolean}
 | 
			
		||||
       */
 | 
			
		||||
      this.bot = Boolean(data.bot);
 | 
			
		||||
      if (this.bot == true) {
 | 
			
		||||
        this.applications = new ApplicationCommandManager(this.client, undefined, this);
 | 
			
		||||
      }
 | 
			
		||||
    } else if (!this.partial && typeof this.bot !== 'boolean') {
 | 
			
		||||
      this.bot = false;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								typings/index.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								typings/index.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -251,6 +251,9 @@ export class ApplicationCommand<PermissionsFetchType = {}> extends Base {
 | 
			
		||||
  private static transformOption(option: ApplicationCommandOptionData, received?: boolean): unknown;
 | 
			
		||||
  private static transformCommand(command: ApplicationCommandData): RESTPostAPIApplicationCommandsJSONBody;
 | 
			
		||||
  private static isAPICommandData(command: object): command is RESTPostAPIApplicationCommandsJSONBody;
 | 
			
		||||
  // Add
 | 
			
		||||
  public static sendSlashCommand(message: Message, options?: Array<string>): Promise<Boolean>;
 | 
			
		||||
  public static sendContextMenu(message: Message): Promise<Boolean>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type ApplicationResolvable = Application | Activity | Snowflake;
 | 
			
		||||
@@ -901,7 +904,7 @@ export class Guild extends AnonymousGuild {
 | 
			
		||||
  public available: boolean;
 | 
			
		||||
  public bans: GuildBanManager;
 | 
			
		||||
  public channels: GuildChannelManager;
 | 
			
		||||
  public commands: GuildApplicationCommandManager;
 | 
			
		||||
  // public commands: GuildApplicationCommandManager;
 | 
			
		||||
  public defaultMessageNotifications: DefaultMessageNotificationLevel | number;
 | 
			
		||||
  /** @deprecated This will be removed in the next major version, see https://github.com/discordjs/discord.js/issues/7091 */
 | 
			
		||||
  public deleted: boolean;
 | 
			
		||||
@@ -2902,7 +2905,7 @@ export class ApplicationCommandManager<
 | 
			
		||||
  PermissionsOptionsExtras = { guild: GuildResolvable },
 | 
			
		||||
  PermissionsGuildType = null,
 | 
			
		||||
> extends CachedManager<Snowflake, ApplicationCommandScope, ApplicationCommandResolvable> {
 | 
			
		||||
  protected constructor(client: Client, iterable?: Iterable<unknown>);
 | 
			
		||||
  protected constructor(client: Client, iterable?: Iterable<unknown>, user: User);
 | 
			
		||||
  public permissions: ApplicationCommandPermissionsManager<
 | 
			
		||||
    { command?: ApplicationCommandResolvable } & PermissionsOptionsExtras,
 | 
			
		||||
    { command: ApplicationCommandResolvable } & PermissionsOptionsExtras,
 | 
			
		||||
@@ -2949,7 +2952,7 @@ export class ApplicationCommandPermissionsManager<
 | 
			
		||||
  GuildType,
 | 
			
		||||
  CommandIdType,
 | 
			
		||||
> extends BaseManager {
 | 
			
		||||
  private constructor(manager: ApplicationCommandManager | GuildApplicationCommandManager | ApplicationCommand);
 | 
			
		||||
  private constructor(manager: ApplicationCommandManager | GuildApplicationCommandManager | ApplicationCommand, user: User);
 | 
			
		||||
  private manager: ApplicationCommandManager | GuildApplicationCommandManager | ApplicationCommand;
 | 
			
		||||
 | 
			
		||||
  public client: Client;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user