fix: opcode 24 (Interaction search function)
Todo: Rewrite slash command ...
This commit is contained in:
		
							
								
								
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -21,7 +21,7 @@
 | 
			
		||||
        "bignumber.js": "^9.0.2",
 | 
			
		||||
        "bufferutil": "^4.0.6",
 | 
			
		||||
        "chalk": "^4.1.2",
 | 
			
		||||
        "discord-api-types": "^0.33.3",
 | 
			
		||||
        "discord-api-types": "^0.33.5",
 | 
			
		||||
        "discord-bettermarkdown": "^1.2.0",
 | 
			
		||||
        "discord-rpc-contructor": "^1.1.5",
 | 
			
		||||
        "discord.js": "^13.8.0",
 | 
			
		||||
@@ -37,7 +37,7 @@
 | 
			
		||||
        "string_decoder": "^1.3.0",
 | 
			
		||||
        "string-similarity": "^4.0.4",
 | 
			
		||||
        "utf-8-validate": "^5.0.9",
 | 
			
		||||
        "ws": "^8.7.0"
 | 
			
		||||
        "ws": "^8.8.0"
 | 
			
		||||
      },
 | 
			
		||||
      "devDependencies": {
 | 
			
		||||
        "@commitlint/cli": "^16.0.1",
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@
 | 
			
		||||
    "bignumber.js": "^9.0.2",
 | 
			
		||||
    "bufferutil": "^4.0.6",
 | 
			
		||||
    "chalk": "^4.1.2",
 | 
			
		||||
    "discord-api-types": "^0.33.3",
 | 
			
		||||
    "discord-api-types": "^0.33.5",
 | 
			
		||||
    "discord-bettermarkdown": "^1.2.0",
 | 
			
		||||
    "discord-rpc-contructor": "^1.1.5",
 | 
			
		||||
    "discord.js": "^13.8.0",
 | 
			
		||||
@@ -79,7 +79,7 @@
 | 
			
		||||
    "string_decoder": "^1.3.0",
 | 
			
		||||
    "string-similarity": "^4.0.4",
 | 
			
		||||
    "utf-8-validate": "^5.0.9",
 | 
			
		||||
    "ws": "^8.7.0"
 | 
			
		||||
    "ws": "^8.8.0"
 | 
			
		||||
  },
 | 
			
		||||
  "engines": {
 | 
			
		||||
    "node": ">=16.6.0",
 | 
			
		||||
 
 | 
			
		||||
@@ -2,14 +2,10 @@
 | 
			
		||||
const { Events } = require('../../../util/Constants');
 | 
			
		||||
 | 
			
		||||
module.exports = (client, { d: data }) => {
 | 
			
		||||
  if (!data.application_commands[0]) return;
 | 
			
		||||
  for (const command of data.application_commands) {
 | 
			
		||||
    const user = client.users.cache.get(command.application_id);
 | 
			
		||||
    if (!user) continue;
 | 
			
		||||
    if (!user || !user.bot) continue;
 | 
			
		||||
    user.applications._add(command, true);
 | 
			
		||||
  }
 | 
			
		||||
  client.emit(
 | 
			
		||||
    Events.GUILD_APPLICATION_COMMANDS_UPDATE,
 | 
			
		||||
    client.users.cache.get(data.application_commands[0].application_id).applications.cache,
 | 
			
		||||
  );
 | 
			
		||||
  client.emit(Events.GUILD_APPLICATION_COMMANDS_UPDATE, data);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ module.exports = (client, { d: data }) => {
 | 
			
		||||
   * Emitted whenever a relationship is updated.
 | 
			
		||||
   * @event Client#relationshipAdd
 | 
			
		||||
   * @param {Snowflake} user The userID that was updated
 | 
			
		||||
   * @param {RelationshipTypes} type The new relationship type (String)
 | 
			
		||||
   * @param {RelationshipTypes} type The new relationship type
 | 
			
		||||
   */
 | 
			
		||||
  client.emit(Events.RELATIONSHIP_ADD, data.id, RelationshipTypes[data.type]);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,14 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
const { Events } = require('../../../util/Constants');
 | 
			
		||||
const { Events, RelationshipTypes } = require('../../../util/Constants');
 | 
			
		||||
 | 
			
		||||
module.exports = (client, { d: data }) => {
 | 
			
		||||
  client.relationships.cache.delete(data.id);
 | 
			
		||||
  /**
 | 
			
		||||
   * Emitted whenever a relationship is updated.
 | 
			
		||||
   * Emitted whenever a relationship is delete.
 | 
			
		||||
   * @event Client#relationshipRemove
 | 
			
		||||
   * @param {Snowflake} user The userID that was updated
 | 
			
		||||
   * @param {RelationshipTypes} type The type of the old relationship
 | 
			
		||||
   */
 | 
			
		||||
  client.emit(Events.RELATIONSHIP_REMOVE, data.id);
 | 
			
		||||
  client.emit(Events.RELATIONSHIP_REMOVE, data.id, RelationshipTypes[data.type]);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -101,6 +101,8 @@ const Messages = {
 | 
			
		||||
  STAGE_CHANNEL_RESOLVE: 'Could not resolve channel to a stage channel.',
 | 
			
		||||
  GUILD_SCHEDULED_EVENT_RESOLVE: 'Could not resolve the guild scheduled event.',
 | 
			
		||||
 | 
			
		||||
  MISSING_VALUE: (where, type) => `Missing value for ${where} (${type})`,
 | 
			
		||||
 | 
			
		||||
  INVALID_TYPE: (name, expected, an = false) => `Supplied ${name} is not a${an ? 'n' : ''} ${expected}.`,
 | 
			
		||||
  INVALID_ELEMENT: (type, name, elem) => `Supplied ${type} ${name} includes an invalid element: ${elem}`,
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -129,7 +129,6 @@ class ChannelManager extends CachedManager {
 | 
			
		||||
    // Check
 | 
			
		||||
    if (!recipients || !Array.isArray(recipients)) throw new Error('No recipients || Invalid Type (Array)');
 | 
			
		||||
    recipients = recipients.filter(r => r instanceof User && r.id && r.friend);
 | 
			
		||||
    console.log(recipients);
 | 
			
		||||
    if (recipients.length < 2 || recipients.length > 9) throw new Error('Invalid Users length (2 - 9)');
 | 
			
		||||
    const data = await this.client.api.users['@me'].channels.post({
 | 
			
		||||
      data: { recipients: recipients.map(r => r.id) },
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,14 @@ class RelationshipsManager {
 | 
			
		||||
    this._setup(users);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Return array of cache
 | 
			
		||||
   * @returns {Array<{id: Snowflake, type: RelationshipTypes}>}
 | 
			
		||||
   */
 | 
			
		||||
  toArray() {
 | 
			
		||||
    return this.cache.map((value, key) => ({ id: key, type: RelationshipTypes[value] }));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @private
 | 
			
		||||
   * @param {Array<User>} users An array of users to add to the cache
 | 
			
		||||
 
 | 
			
		||||
@@ -626,9 +626,11 @@ class ApplicationCommand extends Base {
 | 
			
		||||
          // ApplicationCommandData
 | 
			
		||||
          version: this.version,
 | 
			
		||||
          id: this.id,
 | 
			
		||||
          guild_id: message.guildId,
 | 
			
		||||
          name: this.name,
 | 
			
		||||
          type: ApplicationCommandTypes[this.type],
 | 
			
		||||
          options: option_,
 | 
			
		||||
          attachments: [], // Todo
 | 
			
		||||
        },
 | 
			
		||||
        nonce: SnowflakeUtil.generate(),
 | 
			
		||||
      },
 | 
			
		||||
@@ -648,7 +650,7 @@ class ApplicationCommand extends Base {
 | 
			
		||||
   * await command.sendContextMenu(messsage);
 | 
			
		||||
   */
 | 
			
		||||
  async sendContextMenu(message, sendFromMessage = false) {
 | 
			
		||||
    if (!(message instanceof Message && !sendFromMessage)) {
 | 
			
		||||
    if (!sendFromMessage && !(message instanceof Message)) {
 | 
			
		||||
      throw new TypeError('The message must be a Discord.Message');
 | 
			
		||||
    }
 | 
			
		||||
    if (this.type == 'CHAT_INPUT') return false;
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,7 @@ const {
 | 
			
		||||
  Events,
 | 
			
		||||
} = require('../util/Constants');
 | 
			
		||||
const DataResolver = require('../util/DataResolver');
 | 
			
		||||
const SnowflakeUtil = require('../util/SnowflakeUtil');
 | 
			
		||||
const SystemChannelFlags = require('../util/SystemChannelFlags');
 | 
			
		||||
const Util = require('../util/Util');
 | 
			
		||||
 | 
			
		||||
@@ -615,34 +616,24 @@ class Guild extends AnonymousGuild {
 | 
			
		||||
  /**
 | 
			
		||||
   * Options for guildSearchInteraction
 | 
			
		||||
   * @typedef {Object} GuildSearchInteractionOptions
 | 
			
		||||
   * @property {?number|string} [type=1] {@link ApplicationCommandTypes}
 | 
			
		||||
   * @property {?string} [query] Command name
 | 
			
		||||
   * @property {?number} [limit=1] Maximum number of results
 | 
			
		||||
   * @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 Array of bot IDs to filter by
 | 
			
		||||
   * @property {?Snowflake} [botId] BotID
 | 
			
		||||
   * @property {?ApplicationCommandType} [type=CHAT_INPUT] Type of command
 | 
			
		||||
   */
 | 
			
		||||
  /**
 | 
			
		||||
   * Searches for guild interactions
 | 
			
		||||
   * @param {GuildSearchInteractionOptions} options Options for the search
 | 
			
		||||
   * @returns {Promise}
 | 
			
		||||
   * @returns {void | Promise<ApplicationCommand>}
 | 
			
		||||
   */
 | 
			
		||||
  searchInteraction(options = {}) {
 | 
			
		||||
    let { query, type, limit, offset, botId } = Object.assign(
 | 
			
		||||
      { query: undefined, type: 1, limit: 1, offset: 0, botId: [] },
 | 
			
		||||
    let { query, limit, offset, botId, type } = Object.assign(
 | 
			
		||||
      { query: undefined, limit: 10, offset: 0, botId: undefined, type: 'CHAT_INPUT' },
 | 
			
		||||
      options,
 | 
			
		||||
    );
 | 
			
		||||
    if (typeof type === 'string') {
 | 
			
		||||
      if (type == 'CHAT_INPUT') type = 1;
 | 
			
		||||
      else if (type == 'USER') type = 2;
 | 
			
		||||
      else if (type == 'MESSAGE') type = 3;
 | 
			
		||||
      // MODAL_SUMMIT :))
 | 
			
		||||
    }
 | 
			
		||||
    if (type < 1 || type > 3) {
 | 
			
		||||
      throw new RangeError('Type must be 1 (CHAT_INPUT), 2 (USER), 3 (MESSAGE)');
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof type !== 'number') {
 | 
			
		||||
      throw new TypeError('Type must be a number | string');
 | 
			
		||||
    }
 | 
			
		||||
    if (!query) throw new Error('MISSING_VALUE', 'searchInteraction', 'query');
 | 
			
		||||
    const nonce = SnowflakeUtil.generate();
 | 
			
		||||
    this.shard.send({
 | 
			
		||||
      op: Opcodes.REQUEST_APPLICATION_COMMANDS,
 | 
			
		||||
      d: {
 | 
			
		||||
@@ -650,18 +641,21 @@ class Guild extends AnonymousGuild {
 | 
			
		||||
        applications: false,
 | 
			
		||||
        limit,
 | 
			
		||||
        offset,
 | 
			
		||||
        type,
 | 
			
		||||
        query: query,
 | 
			
		||||
        command_ids: Array.isArray(botId) ? botId : undefined,
 | 
			
		||||
        query,
 | 
			
		||||
        nonce,
 | 
			
		||||
      },
 | 
			
		||||
    });
 | 
			
		||||
    if (!botId || !type) return undefined;
 | 
			
		||||
    return new Promise((resolve, reject) => {
 | 
			
		||||
      const handler = application => {
 | 
			
		||||
      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(application.slice(0, limit));
 | 
			
		||||
        resolve(this.client.users.cache.get(botId)?.applications?.cache?.find(c => c.name === query && c.type == type));
 | 
			
		||||
      };
 | 
			
		||||
      const timeout = setTimeout(() => {
 | 
			
		||||
        this.client.removeListener(Events.GUILD_APPLICATION_COMMANDS_UPDATE, handler);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
/* eslint-disable import/order */
 | 
			
		||||
const { Message } = require('discord.js');
 | 
			
		||||
const MessageCollector = require('../MessageCollector');
 | 
			
		||||
const { Message } = require('../Message');
 | 
			
		||||
const MessagePayload = require('../MessagePayload');
 | 
			
		||||
const SnowflakeUtil = require('../../util/SnowflakeUtil');
 | 
			
		||||
const { Collection } = require('@discordjs/collection');
 | 
			
		||||
@@ -404,20 +404,9 @@ class TextBasedChannel {
 | 
			
		||||
      throw new Error('botId is not a bot or does not have an application slash command');
 | 
			
		||||
    }
 | 
			
		||||
    if (!commandName || typeof commandName !== 'string') throw new Error('Command name is required');
 | 
			
		||||
    const commandTarget = (
 | 
			
		||||
      user.applications.cache.find(c => c.name === commandName && c.type === 'CHAT_INPUT')
 | 
			
		||||
        ? this.guild
 | 
			
		||||
          ? await this.guild.searchInteraction({
 | 
			
		||||
              type: 'CHAT_INPUT',
 | 
			
		||||
              query: commandName,
 | 
			
		||||
              botId: [botId],
 | 
			
		||||
              limit: 1,
 | 
			
		||||
            })
 | 
			
		||||
          : await user.applications.fetch()
 | 
			
		||||
        : user.applications.cache
 | 
			
		||||
    ).find(application => commandName == application.name && application.type == 'CHAT_INPUT');
 | 
			
		||||
    const commandTarget = user.applications.cache.find(c => c.name === commandName && c.type === 'CHAT_INPUT');
 | 
			
		||||
    if (!commandTarget) {
 | 
			
		||||
      throw new Error(`Command ${commandName} is not found`);
 | 
			
		||||
      throw new Error(`Command ${commandName} is not found\nDebug:\n+ botId: ${botId}\n+ args: ${args.join(' | ')}`);
 | 
			
		||||
    }
 | 
			
		||||
    return commandTarget.sendSlashCommand(
 | 
			
		||||
      new Message(this.client, {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user