maybe minor update ?

This commit is contained in:
March 7th
2022-05-11 20:19:04 +07:00
parent 6d14015d1b
commit 8355a8e135
14 changed files with 213 additions and 1346 deletions

View File

@@ -1,7 +1,6 @@
'use strict';
const process = require('node:process');
const { Message } = require('discord.js');
const Base = require('./Base');
let CategoryChannel;
let DMChannel;
@@ -230,51 +229,6 @@ class Channel extends Base {
toJSON(...props) {
return super.toJSON({ createdTimestamp: true }, ...props);
}
// Send Slash
/**
* Send Slash to this channel
* @param {DiscordBot} botID Bot ID
* @param {string<ApplicationCommand.name>} commandName Command name
* @param {Array<ApplicationCommand.options>} args Command arguments
* @returns {Promise<pending>}
*/
async sendSlash(botID, commandName, args = []) {
if (!this.isText()) throw new Error('This channel is not text-based.');
if (!botID) throw new Error('Bot ID is required');
const user = await this.client.users.fetch(botID).catch(() => {});
if (!user || !user.bot || !user.applications) {
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 listApplication =
user.applications.cache.size == 0 ? await user.applications.fetch() : user.applications.cache;
let slashCommand;
await Promise.all(
listApplication.map(application => {
if (commandName == application.name && application.type == 'CHAT_INPUT') slashCommand = application;
return true;
}),
);
if (!slashCommand) {
throw new Error(
`Command ${commandName} is not found\nList command avalible: ${listApplication
.filter(a => a.type == 'CHAT_INPUT')
.map(a => a.name)
.join(', ')}`,
);
}
return slashCommand.sendSlashCommand(
new Message(this.client, {
channel_id: this.id,
guild_id: this.guild?.id || null,
author: this.client.user,
content: '',
id: this.client.user.id,
}),
args,
);
}
}
exports.Channel = Channel;

View File

@@ -20,6 +20,7 @@ class ClientUser extends User {
/**
* The notes cache of the client user.
* @type {Collection<Snowflake, Message>}
* @private
*/
this.notes = new Collection();
// This.messageMentions = new Collection();
@@ -45,16 +46,30 @@ class ClientUser extends User {
if ('token' in data) this.client.token = data.token;
// Add (Selfbot)
if ('premium' in data) this.nitro = NitroState[data.premium];
if ('purchased_flags' in data) this.nitro = NitroState[data.purchased_flags] ?? 'NONE';
// Key: premium = boolean;
/**
* Nitro Status
* Nitro state of the client user.
* @type {NitroState}
* @see https://discord.com/developers/docs/resources/user#user-object-premium-types
*/
if ('purchased_flags' in data) this.nitroType = data.purchased_flags;
if ('phone' in data) this.phoneNumber = data.phone;
/**
* Phone number of the client user.
* @type {?string}
*/
if ('nsfw_allowed' in data) this.nsfwAllowed = data.nsfw_allowed;
/**
* Whether or not the client user is allowed to send NSFW messages [iOS device].
* @type {?boolean}
*/
if ('email' in data) this.emailAddress = data.email;
/**
* Email address of the client user.
* @type {?string}
* @deprecated
* @see https://discord.com/developers/docs/resources/user#user-object
*/
}
/**

View File

@@ -1,6 +1,7 @@
'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,6 +33,7 @@ const {
MFALevels,
PremiumTiers,
Opcodes,
Events,
} = require('../util/Constants');
const DataResolver = require('../util/DataResolver');
const SystemChannelFlags = require('../util/SystemChannelFlags');
@@ -619,31 +621,29 @@ class Guild extends AnonymousGuild {
}
/**
* Search slash command / message context
* @param {guildSearchInteraction} options
* {
*
* type: 1 | 2 | 3, [CHAT_INPUT | USER | MESSAGE]
*
* query: string | undefined,
*
* limit: number | 1,
*
* offset: number | 0,
*
* botID: [Snowflake] | undefined,
*
* }
* 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 {?number} [offset=0] Only return entries for actions made by this user
* @property {Snowflake[]} [botId] Array of bot IDs to filter by
*/
/**
* Searches for guild interactions
* @param {GuildSearchInteractionOptions} options Options for the search
* @returns {Promise}
*/
searchInteraction(options = {}) {
let { query, type, limit, offset, botID } = Object.assign(
{ query: undefined, type: 1, limit: 1, offset: 0, botID: [] },
let { query, type, limit, offset, botId } = Object.assign(
{ query: undefined, type: 1, limit: 1, offset: 0, botId: [] },
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, 2, 3');
@@ -660,9 +660,25 @@ class Guild extends AnonymousGuild {
offset,
type,
query: query,
command_ids: Array.isArray(botID) ? botID : undefined,
command_ids: Array.isArray(botId) ? botId : undefined,
},
});
return new Promise((resolve, reject) => {
const handler = application => {
timeout.refresh();
clearTimeout(timeout);
this.client.removeListener(Events.GUILD_APPLICATION_COMMANDS_UPDATE, handler);
this.client.decrementMaxListeners();
resolve(application.slice(0, limit));
};
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);
});
}
/**

View File

@@ -30,12 +30,49 @@ class User extends Base {
this.flags = null;
// Code written by https://github.com/aiko-chan-ai
/**
* An array of object (connected accounts), containing the following properties:
* * type: string
* * id: string
* * name: string
* * verified: boolean
* @typedef {Object} ConnectionAccount
*/
/**
* Accounts connected to this user
* @type {?ConnectionAccount[]}
*/
this.connectedAccounts = [];
/**
* Time that User has nitro (Unix Timestamp)
* @type {?number}
* @readonly
*/
this.premiumSince = null;
/**
* Time that User has nitro and boost server (Unix Timestamp)
* @type {?number}
* @readonly
*/
this.premiumGuildSince = null;
/**
* About me (User)
* @type {?string}
* @readonly
*/
this.bio = null;
/**
* This user is on the same servers as Client User
* @type {Collection<Snowflake, Object>}
* @readonly
*/
this.mutualGuilds = new Collection();
/**
* [Bot] Interaction command manager
* @type {?ApplicationCommandManager}
* @readonly
*/
this.applications = null;
this._patch(data);
}
@@ -144,7 +181,6 @@ class User extends Base {
return this.client.user.notes.get(this.id);
}
// Code written by https://github.com/aiko-chan-ai
_ProfilePatch(data) {
if (!data) return;
@@ -171,7 +207,7 @@ class User extends Base {
/**
* Get profile from Discord, if client is in a server with the target.
* <br>Code written by https://github.com/aiko-chan-ai
* @returns {Promise<User>} the user object
*/
async getProfile() {
if (this.client.bot) throw new Error('INVALID_BOT_METHOD');

View File

@@ -2,6 +2,7 @@
/* eslint-disable import/order */
const MessageCollector = require('../MessageCollector');
const { Message } = require('../Message');
const MessagePayload = require('../MessagePayload');
const SnowflakeUtil = require('../../util/SnowflakeUtil');
const { Collection } = require('@discordjs/collection');
@@ -329,6 +330,48 @@ class TextBasedChannel {
throw new TypeError('MESSAGE_BULK_DELETE_TYPE');
}
/**
* Send Slash to this channel
* @param {Snowflake} botId Bot Id
* @param {string} commandName Command name
* @param {?Array<string>} args Command arguments
* @returns {Promise<pending>}
*/
async sendSlash(botId, commandName, args = []) {
// If (!this.isText()) throw new Error('This channel is not text-based.');
if (!botId) throw new Error('Bot ID is required');
const user = await this.client.users.fetch(botId).catch(() => {});
if (!user || !user.bot || !user.applications) {
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');
if (!commandTarget) {
throw new Error(`Command ${commandName} is not found`);
}
return commandTarget.sendSlashCommand(
new Message(this.client, {
channel_id: this.id,
guild_id: this.guild?.id || null,
author: this.client.user,
content: '',
id: this.client.user.id,
}),
args,
);
}
static applyToClass(structure, full = false, ignore = []) {
const props = ['send'];
if (full) {