Merge pull request #300 from aiko-chan-ai/dev

feat: Appliaction
This commit is contained in:
Cinnamon 2022-09-10 18:36:36 +07:00 committed by GitHub
commit 98b8f9335c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 104 additions and 84 deletions

View File

@ -16,7 +16,7 @@ const Message = lazy(() => require('../structures/Message').Message);
* @extends {Base} * @extends {Base}
*/ */
class ApplicationCommand extends Base { class ApplicationCommand extends Base {
constructor(client, data, guild, guildId) { constructor(client, data) {
super(client); super(client);
/** /**
@ -31,19 +31,6 @@ class ApplicationCommand extends Base {
*/ */
this.applicationId = data.application_id; this.applicationId = data.application_id;
/**
* The guild this command is part of
* @type {?Guild}
*/
this.guild = guild ?? null;
/**
* The guild's id this command is part of, this may be non-null when `guild` is `null` if the command
* was fetched from the `ApplicationCommandManager`
* @type {?Snowflake}
*/
this.guildId = guild?.id ?? guildId ?? null;
/** /**
* The manager for permissions of this command on its guild or arbitrary guilds when the command is global * The manager for permissions of this command on its guild or arbitrary guilds when the command is global
* @type {ApplicationCommandPermissionsManager} * @type {ApplicationCommandPermissionsManager}
@ -61,7 +48,24 @@ class ApplicationCommand extends Base {
this._patch(data); this._patch(data);
} }
/**
* The guild this command is part of
* @type {?Guild}
*/
get guild() {
return this.client.guilds.resolve(this.guildId);
}
_patch(data) { _patch(data) {
if ('guild_id' in data) {
/**
* The guild's id this command is part of, this may be non-null when `guild` is `null` if the command
* was fetched from the `ApplicationCommandManager`
* @type {?Snowflake}
*/
this.guildId = data.guild_id ?? null;
}
if ('name' in data) { if ('name' in data) {
/** /**
* The name of this command * The name of this command
@ -784,32 +788,11 @@ class ApplicationCommand extends Base {
attachmentsBuffer.push({ attachment: data.attachment, name: data.name, file: resource }); attachmentsBuffer.push({ attachment: data.attachment, name: data.name, file: resource });
return id; return id;
} }
const getDataPost = (guildAdd = false, dataAdd = [], nonce, autocomplete = false) => { const getDataPost = (dataAdd = [], nonce, autocomplete = false) => {
if (!Array.isArray(dataAdd) && typeof dataAdd == 'object') { if (!Array.isArray(dataAdd) && typeof dataAdd == 'object') {
dataAdd = [dataAdd]; dataAdd = [dataAdd];
} }
if (guildAdd) { const data = {
return {
type: autocomplete ? 4 : 2, // Slash command, context menu
// Type: 4: Auto-complete
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: dataAdd,
attachments: attachments,
guild_id: message.guildId,
},
nonce,
};
} else {
return {
type: autocomplete ? 4 : 2, // Slash command, context menu type: autocomplete ? 4 : 2, // Slash command, context menu
// Type: 4: Auto-complete // Type: 4: Auto-complete
application_id: this.applicationId, application_id: this.applicationId,
@ -827,23 +810,17 @@ class ApplicationCommand extends Base {
}, },
nonce, nonce,
}; };
if (this.guildId) {
data.data.guild_id = message.guildId;
} }
return data;
}; };
const getAutoResponse = async (sendData, value) => { const getAutoResponse = async (sendData, value) => {
let nonce = SnowflakeUtil.generate(); let nonce = SnowflakeUtil.generate();
const data = getDataPost(false, sendData, nonce, true); const data = getDataPost(sendData, nonce, true);
await this.client.api.interactions await this.client.api.interactions.post({
.post({
data, data,
files: attachmentsBuffer, files: attachmentsBuffer,
})
.catch(async () => {
nonce = SnowflakeUtil.generate();
const data_ = getDataPost(true, sendData, nonce);
await this.client.api.interactions.post({
body: data_,
files: attachmentsBuffer,
});
}); });
return new Promise(resolve => { return new Promise(resolve => {
const handler = data => { const handler = data => {
@ -866,19 +843,10 @@ class ApplicationCommand extends Base {
}; };
const sendData = async (optionsData = []) => { const sendData = async (optionsData = []) => {
let nonce = SnowflakeUtil.generate(); let nonce = SnowflakeUtil.generate();
const data = getDataPost(false, optionsData, nonce); const data = getDataPost(optionsData, nonce);
await this.client.api.interactions await this.client.api.interactions.post({
.post({
body: data, body: data,
files: attachmentsBuffer, files: attachmentsBuffer,
})
.catch(async () => {
nonce = SnowflakeUtil.generate();
const data_ = getDataPost(true, optionsData, nonce);
await this.client.api.interactions.post({
body: data_,
files: attachmentsBuffer,
});
}); });
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const handler = data => { const handler = data => {
@ -927,6 +895,58 @@ class ApplicationCommand extends Base {
} }
} }
} }
/**
* Message Context Menu
* @param {Message} message Discord Message
* @returns {Promise<InteractionResponseBody>}
*/
async sendContextMenu(message) {
if (!(message instanceof Message())) {
throw new TypeError('The message must be a Discord.Message');
}
if (this.type == 'CHAT_INPUT') return false;
const nonce = SnowflakeUtil.generate();
const data = {
type: 2, // Slash command, context menu
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,
},
nonce,
};
if (this.guildId) {
data.data.guild_id = message.guildId;
}
await this.client.api.interactions.post({
body: data,
});
return new Promise((resolve, reject) => {
const handler = data => {
timeout.refresh();
if (data.metadata.nonce !== nonce) return;
clearTimeout(timeout);
this.client.removeListener('interactionResponse', handler);
this.client.decrementMaxListeners();
if (data.status) resolve(data.metadata);
else reject(data.metadata);
};
const timeout = setTimeout(() => {
this.client.removeListener('interactionResponse', handler);
this.client.decrementMaxListeners();
reject(new Error('INTERACTION_TIMEOUT'));
}, 15_000).unref();
this.client.incrementMaxListeners();
this.client.on('interactionResponse', handler);
});
}
} }
module.exports = ApplicationCommand; module.exports = ApplicationCommand;

4
typings/index.d.ts vendored
View File

@ -445,7 +445,7 @@ export class DeveloperPortalManager extends BaseManager {
} }
export class ApplicationCommand<PermissionsFetchType = {}> extends Base { export class ApplicationCommand<PermissionsFetchType = {}> extends Base {
private constructor(client: Client, data: RawApplicationCommandData, guild?: Guild, guildId?: Snowflake); private constructor(client: Client, data: RawApplicationCommandData);
public applicationId: Snowflake; public applicationId: Snowflake;
public readonly createdAt: Date; public readonly createdAt: Date;
public readonly createdTimestamp: number; public readonly createdTimestamp: number;
@ -454,7 +454,7 @@ export class ApplicationCommand<PermissionsFetchType = {}> extends Base {
public description: string; public description: string;
public descriptionLocalizations: LocalizationMap | null; public descriptionLocalizations: LocalizationMap | null;
public descriptionLocalized: string | null; public descriptionLocalized: string | null;
public guild: Guild | null; public readonly guild: Guild | null;
public guildId: Snowflake | null; public guildId: Snowflake | null;
public readonly manager: ApplicationCommandManager; public readonly manager: ApplicationCommandManager;
public id: Snowflake; public id: Snowflake;