mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
feat(Interactions): add InteractionWebhook for better internals (#5712)
This commit is contained in:
@@ -24,6 +24,19 @@ class WebhookClient extends BaseClient {
|
||||
this.id = id;
|
||||
Object.defineProperty(this, 'token', { value: token, writable: true, configurable: true });
|
||||
}
|
||||
|
||||
// These are here only for documentation purposes - they are implemented by Webhook
|
||||
/* eslint-disable no-empty-function */
|
||||
send() {}
|
||||
sendSlackMessage() {}
|
||||
fetchMessage() {}
|
||||
edit() {}
|
||||
editMessage() {}
|
||||
delete() {}
|
||||
deleteMessage() {}
|
||||
get createdTimestamp() {}
|
||||
get createdAt() {}
|
||||
get url() {}
|
||||
}
|
||||
|
||||
Webhook.applyToClass(WebhookClient);
|
||||
|
||||
@@ -91,6 +91,7 @@ module.exports = {
|
||||
Integration: require('./structures/Integration'),
|
||||
IntegrationApplication: require('./structures/IntegrationApplication'),
|
||||
Interaction: require('./structures/Interaction'),
|
||||
InteractionWebhook: require('./structures/InteractionWebhook'),
|
||||
Invite: require('./structures/Invite'),
|
||||
Message: require('./structures/Message'),
|
||||
MessageActionRow: require('./structures/MessageActionRow'),
|
||||
|
||||
@@ -81,7 +81,8 @@ class APIMessage {
|
||||
*/
|
||||
get isInteraction() {
|
||||
const Interaction = require('./Interaction');
|
||||
return this.target instanceof Interaction;
|
||||
const InteractionWebhook = require('./InteractionWebhook');
|
||||
return this.target instanceof Interaction || this.target instanceof InteractionWebhook;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -372,10 +373,15 @@ class APIMessage {
|
||||
*/
|
||||
static create(target, content, options, extra = {}) {
|
||||
const Interaction = require('./Interaction');
|
||||
const InteractionWebhook = require('./InteractionWebhook');
|
||||
const Webhook = require('./Webhook');
|
||||
const WebhookClient = require('../client/WebhookClient');
|
||||
|
||||
const isWebhook = target instanceof Interaction || target instanceof Webhook || target instanceof WebhookClient;
|
||||
const isWebhook =
|
||||
target instanceof Interaction ||
|
||||
target instanceof InteractionWebhook ||
|
||||
target instanceof Webhook ||
|
||||
target instanceof WebhookClient;
|
||||
const transformed = this.transformOptions(content, options, extra, isWebhook);
|
||||
return new this(target, transformed);
|
||||
}
|
||||
@@ -385,7 +391,7 @@ module.exports = APIMessage;
|
||||
|
||||
/**
|
||||
* A target for a message.
|
||||
* @typedef {TextChannel|DMChannel|User|GuildMember|Webhook|WebhookClient|Interaction} MessageTarget
|
||||
* @typedef {TextChannel|DMChannel|User|GuildMember|Webhook|WebhookClient|Interaction|InteractionWebhook} MessageTarget
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
const Interaction = require('./Interaction');
|
||||
const InteractionWebhook = require('./InteractionWebhook');
|
||||
const InteractionResponses = require('./interfaces/InteractionResponses');
|
||||
const WebhookClient = require('../client/WebhookClient');
|
||||
const Collection = require('../util/Collection');
|
||||
const { ApplicationCommandOptionTypes } = require('../util/Constants');
|
||||
|
||||
@@ -53,10 +53,10 @@ class CommandInteraction extends Interaction {
|
||||
this.replied = false;
|
||||
|
||||
/**
|
||||
* An associated webhook client, can be used to create deferred replies
|
||||
* @type {WebhookClient}
|
||||
* An associated interaction webhook, can be used to further interact with this interaction
|
||||
* @type {InteractionWebhook}
|
||||
*/
|
||||
this.webhook = new WebhookClient(this.applicationID, this.token, this.client.options);
|
||||
this.webhook = new InteractionWebhook(this.client, this.applicationID, this.token);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
44
src/structures/InteractionWebhook.js
Normal file
44
src/structures/InteractionWebhook.js
Normal file
@@ -0,0 +1,44 @@
|
||||
'use strict';
|
||||
|
||||
const Webhook = require('./Webhook');
|
||||
|
||||
/**
|
||||
* Represents a webhook for an Interaction
|
||||
* @implements {Webhook}
|
||||
*/
|
||||
class InteractionWebhook {
|
||||
/**
|
||||
* @param {Client} client The instantiating client
|
||||
* @param {Snowflake} id ID of the application
|
||||
* @param {string} token Token of the interaction
|
||||
*/
|
||||
constructor(client, id, token) {
|
||||
/**
|
||||
* The client that instantiated the interaction webhook
|
||||
* @name InteractionWebhook#client
|
||||
* @type {Client}
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(this, 'client', { value: client });
|
||||
this.id = id;
|
||||
Object.defineProperty(this, 'token', { value: token, writable: true, configurable: true });
|
||||
}
|
||||
|
||||
// These are here only for documentation purposes - they are implemented by Webhook
|
||||
/* eslint-disable no-empty-function, valid-jsdoc */
|
||||
/**
|
||||
* Sends a message with this webhook.
|
||||
* @param {string|APIMessage|MessageAdditions} content The content for the reply
|
||||
* @param {InteractionReplyOptions} [options] Additional options for the reply
|
||||
* @returns {Promise<Message|Object>}
|
||||
*/
|
||||
send() {}
|
||||
fetchMessage() {}
|
||||
editMessage() {}
|
||||
deleteMessage() {}
|
||||
get url() {}
|
||||
}
|
||||
|
||||
Webhook.applyToClass(InteractionWebhook, ['sendSlackMessage', 'edit', 'delete', 'createdTimestamp', 'createdAt']);
|
||||
|
||||
module.exports = InteractionWebhook;
|
||||
@@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
const Interaction = require('./Interaction');
|
||||
const InteractionWebhook = require('./InteractionWebhook');
|
||||
const InteractionResponses = require('./interfaces/InteractionResponses');
|
||||
const WebhookClient = require('../client/WebhookClient');
|
||||
const { MessageComponentTypes } = require('../util/Constants');
|
||||
|
||||
/**
|
||||
@@ -45,10 +45,10 @@ class MessageComponentInteraction extends Interaction {
|
||||
this.replied = false;
|
||||
|
||||
/**
|
||||
* An associated webhook client, can be used to create deferred replies
|
||||
* @type {WebhookClient}
|
||||
* An associated interaction webhook, can be used to further interact with this interaction
|
||||
* @type {InteractionWebhook}
|
||||
*/
|
||||
this.webhook = new WebhookClient(this.applicationID, this.token, this.client.options);
|
||||
this.webhook = new InteractionWebhook(this.client, this.applicationID, this.token);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -325,7 +325,7 @@ class Webhook {
|
||||
return this.client.rest.cdn.Avatar(this.id, this.avatar, format, size);
|
||||
}
|
||||
|
||||
static applyToClass(structure) {
|
||||
static applyToClass(structure, ignore = []) {
|
||||
for (const prop of [
|
||||
'send',
|
||||
'sendSlackMessage',
|
||||
@@ -338,6 +338,7 @@ class Webhook {
|
||||
'createdAt',
|
||||
'url',
|
||||
]) {
|
||||
if (ignore.includes(prop)) continue;
|
||||
Object.defineProperty(structure.prototype, prop, Object.getOwnPropertyDescriptor(Webhook.prototype, prop));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,9 +93,8 @@ class InteractionResponses {
|
||||
* .then(reply => console.log(`Replied with ${reply.content}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async fetchReply() {
|
||||
const raw = await this.webhook.fetchMessage('@original');
|
||||
return this.channel?.messages.add(raw) ?? raw;
|
||||
fetchReply() {
|
||||
return this.webhook.fetchMessage('@original');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,9 +109,8 @@ class InteractionResponses {
|
||||
* .then(console.log)
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async editReply(content, options) {
|
||||
const raw = await this.webhook.editMessage('@original', content, options);
|
||||
return this.channel?.messages.add(raw) ?? raw;
|
||||
editReply(content, options) {
|
||||
return this.webhook.editMessage('@original', content, options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,16 +133,8 @@ class InteractionResponses {
|
||||
* @param {InteractionReplyOptions} [options] Additional options for the reply
|
||||
* @returns {Promise<Message|Object>}
|
||||
*/
|
||||
async followUp(content, options) {
|
||||
const apiMessage = content instanceof APIMessage ? content : APIMessage.create(this, content, options);
|
||||
const { data, files } = await apiMessage.resolveData().resolveFiles();
|
||||
|
||||
const raw = await this.client.api.webhooks(this.applicationID, this.token).post({
|
||||
data,
|
||||
files,
|
||||
});
|
||||
|
||||
return this.channel?.messages.add(raw) ?? raw;
|
||||
followUp(content, options) {
|
||||
return this.webhook.send(content, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
45
typings/index.d.ts
vendored
45
typings/index.d.ts
vendored
@@ -467,7 +467,7 @@ declare module 'discord.js' {
|
||||
public deferred: boolean;
|
||||
public options: Collection<string, CommandInteractionOption>;
|
||||
public replied: boolean;
|
||||
public webhook: WebhookClient;
|
||||
public webhook: InteractionWebhook;
|
||||
public defer(options?: InteractionDeferOptions): Promise<void>;
|
||||
public deleteReply(): Promise<void>;
|
||||
public editReply(
|
||||
@@ -1139,6 +1139,30 @@ declare module 'discord.js' {
|
||||
public isMessageComponent(): this is MessageComponentInteraction;
|
||||
}
|
||||
|
||||
export class InteractionWebhook extends PartialWebhookMixin() {
|
||||
constructor(client: Client, id: Snowflake, token: string);
|
||||
public token: string;
|
||||
public send(
|
||||
content: string | (InteractionReplyOptions & { split?: false }) | MessageAdditions,
|
||||
): Promise<Message | RawMessage>;
|
||||
public send(options: InteractionReplyOptions & { split: true | SplitOptions }): Promise<(Message | RawMessage)[]>;
|
||||
public send(
|
||||
options: InteractionReplyOptions | APIMessage,
|
||||
): Promise<Message | RawMessage | (Message | RawMessage)[]>;
|
||||
public send(
|
||||
content: string | null,
|
||||
options: (InteractionReplyOptions & { split?: false }) | MessageAdditions,
|
||||
): Promise<Message | RawMessage>;
|
||||
public send(
|
||||
content: string | null,
|
||||
options: InteractionReplyOptions & { split: true | SplitOptions },
|
||||
): Promise<(Message | RawMessage)[]>;
|
||||
public send(
|
||||
content: string | null,
|
||||
options: InteractionReplyOptions,
|
||||
): Promise<Message | RawMessage | (Message | RawMessage)[]>;
|
||||
}
|
||||
|
||||
export class Invite extends Base {
|
||||
constructor(client: Client, data: unknown);
|
||||
public channel: GuildChannel | PartialGroupDMChannel;
|
||||
@@ -1333,7 +1357,7 @@ declare module 'discord.js' {
|
||||
public deferred: boolean;
|
||||
public message: Message | RawMessage;
|
||||
public replied: boolean;
|
||||
public webhook: WebhookClient;
|
||||
public webhook: InteractionWebhook;
|
||||
public defer(options?: InteractionDeferOptions): Promise<void>;
|
||||
public deferUpdate(): Promise<void>;
|
||||
public deleteReply(): Promise<void>;
|
||||
@@ -2498,18 +2522,15 @@ declare module 'discord.js' {
|
||||
stopTyping(force?: boolean): void;
|
||||
}
|
||||
|
||||
function PartialWebhookMixin<T>(Base?: Constructable<T>): Constructable<T & PartialWebhookFields>;
|
||||
function WebhookMixin<T>(Base?: Constructable<T>): Constructable<T & WebhookFields>;
|
||||
|
||||
function VolumeMixin<T>(base: Constructable<T>): Constructable<T & VolumeInterface>;
|
||||
|
||||
interface WebhookFields {
|
||||
interface PartialWebhookFields {
|
||||
id: Snowflake;
|
||||
readonly createdAt: Date;
|
||||
readonly createdTimestamp: number;
|
||||
readonly url: string;
|
||||
delete(reason?: string): Promise<void>;
|
||||
deleteMessage(message: MessageResolvable | '@original'): Promise<void>;
|
||||
edit(options: WebhookEditData): Promise<Webhook>;
|
||||
editMessage(
|
||||
message: MessageResolvable | '@original',
|
||||
content: string | null | APIMessage | MessageAdditions,
|
||||
@@ -2537,7 +2558,14 @@ declare module 'discord.js' {
|
||||
content: string | null,
|
||||
options: WebhookMessageOptions,
|
||||
): Promise<Message | RawMessage | (Message | RawMessage)[]>;
|
||||
sendSlackMessage(body: unknown): Promise<boolean>;
|
||||
}
|
||||
|
||||
interface WebhookFields extends PartialWebhookFields {
|
||||
readonly createdAt: Date;
|
||||
readonly createdTimestamp: number;
|
||||
delete(reason?: string): Promise<void>;
|
||||
edit(options: WebhookEditData): Promise<Webhook>;
|
||||
sendSlackMessage(body: object): Promise<boolean>;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@@ -3532,6 +3560,7 @@ declare module 'discord.js' {
|
||||
|
||||
type MessageTarget =
|
||||
| Interaction
|
||||
| InteractionWebhook
|
||||
| TextChannel
|
||||
| NewsChannel
|
||||
| DMChannel
|
||||
|
||||
Reference in New Issue
Block a user