Skip to content

Commit

Permalink
feat: Allow webhooks to fetch, edit and delete messages in threads (#…
Browse files Browse the repository at this point in the history
…6695)

Co-authored-by: Antonio Román <kyradiscord@gmail.com>
  • Loading branch information
Jiralite and kyranet committed Oct 2, 2021
1 parent cdf65f7 commit 107822d
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 9 deletions.
47 changes: 40 additions & 7 deletions src/structures/Webhook.js
Expand Up @@ -105,6 +105,8 @@ class Webhook {
* @property {MessageAttachment[]} [attachments] Attachments to send with the message
* @property {MessageActionRow[]|MessageActionRowOptions[]} [components]
* Action rows containing interactive components for the message (buttons, select menus)
* @property {Snowflake} [threadId] The id of the thread this message belongs to
* <info>For interaction webhooks, this property is ignored</info>
*/

/**
Expand Down Expand Up @@ -235,18 +237,38 @@ class Webhook {
return this;
}

/**
* Options that can be passed into fetchMessage.
* @typedef {options} WebhookFetchMessageOptions
* @property {boolean} [cache=true] Whether to cache the message.
* @property {Snowflake} [threadId] The id of the thread this message belongs to.
* <info>For interaction webhooks, this property is ignored</info>
*/

/**
* Gets a message that was sent by this webhook.
* @param {Snowflake|'@original'} message The id of the message to fetch
* @param {boolean} [cache=true] Whether to cache the message
* @param {WebhookFetchMessageOptions|boolean} [cacheOrOptions={}] The options to provide to fetch the message.
* A **deprecated** boolean may be passed instead to specify whether to cache the message.
* @returns {Promise<Message|APIMessage>} Returns the raw message data if the webhook was instantiated as a
* {@link WebhookClient} or if the channel is uncached, otherwise a {@link Message} will be returned
*/
async fetchMessage(message, cache = true) {
async fetchMessage(message, cacheOrOptions = { cache: true }) {
if (typeof cacheOrOptions === 'boolean') {
cacheOrOptions = { cache: cacheOrOptions };
}

if (!this.token) throw new Error('WEBHOOK_TOKEN_UNAVAILABLE');

const data = await this.client.api.webhooks(this.id, this.token).messages(message).get();
return this.client.channels?.cache.get(data.channel_id)?.messages._add(data, cache) ?? data;
const data = await this.client.api
.webhooks(this.id, this.token)
.messages(message)
.get({
query: {
thread_id: cacheOrOptions.threadId,
},
});
return this.client.channels?.cache.get(data.channel_id)?.messages._add(data, cacheOrOptions.cache) ?? data;
}

/**
Expand All @@ -269,7 +291,13 @@ class Webhook {
const d = await this.client.api
.webhooks(this.id, this.token)
.messages(typeof message === 'string' ? message : message.id)
.patch({ data, files });
.patch({
data,
files,
query: {
thread_id: messagePayload.options.threadId,
},
});

const messageManager = this.client.channels?.cache.get(d.channel_id)?.messages;
if (!messageManager) return d;
Expand All @@ -294,15 +322,20 @@ class Webhook {
/**
* Delete a message that was sent by this webhook.
* @param {MessageResolvable|'@original'} message The message to delete
* @param {Snowflake} [threadId] The id of the thread this message belongs to
* @returns {Promise<void>}
*/
async deleteMessage(message) {
async deleteMessage(message, threadId) {
if (!this.token) throw new Error('WEBHOOK_TOKEN_UNAVAILABLE');

await this.client.api
.webhooks(this.id, this.token)
.messages(typeof message === 'string' ? message : message.id)
.delete();
.delete({
query: {
thread_id: threadId,
},
});
}

/**
Expand Down
17 changes: 15 additions & 2 deletions typings/index.d.ts
Expand Up @@ -2122,7 +2122,11 @@ export class WebhookClient extends WebhookMixin(BaseClient) {
message: MessageResolvable,
options: string | MessagePayload | WebhookEditMessageOptions,
): Promise<APIMessage>;
public fetchMessage(message: Snowflake, options?: WebhookFetchMessageOptions): Promise<APIMessage>;
/* tslint:disable:unified-signatures */
/** @deprecated */
public fetchMessage(message: Snowflake, cache?: boolean): Promise<APIMessage>;
/* tslint:enable:unified-signatures */
public send(options: string | MessagePayload | WebhookMessageOptions): Promise<APIMessage>;
}

Expand Down Expand Up @@ -2836,12 +2840,16 @@ export function WebhookMixin<T>(Base?: Constructable<T>): Constructable<T & Webh
export interface PartialWebhookFields {
id: Snowflake;
readonly url: string;
deleteMessage(message: MessageResolvable | APIMessage | '@original'): Promise<void>;
deleteMessage(message: MessageResolvable | APIMessage | '@original', threadId?: Snowflake): Promise<void>;
editMessage(
message: MessageResolvable | '@original',
options: string | MessagePayload | WebhookEditMessageOptions,
): Promise<Message | APIMessage>;
fetchMessage(message: Snowflake | '@original', options?: WebhookFetchMessageOptions): Promise<Message | APIMessage>;
/* tslint:disable:unified-signatures */
/** @deprecated */
fetchMessage(message: Snowflake | '@original', cache?: boolean): Promise<Message | APIMessage>;
/* tslint:enable:unified-signatures */
send(options: string | MessagePayload | WebhookMessageOptions): Promise<Message | APIMessage>;
}

Expand Down Expand Up @@ -4869,9 +4877,14 @@ export interface WebhookEditData {

export type WebhookEditMessageOptions = Pick<
WebhookMessageOptions,
'content' | 'embeds' | 'files' | 'allowedMentions' | 'components' | 'attachments'
'content' | 'embeds' | 'files' | 'allowedMentions' | 'components' | 'attachments' | 'threadId'
>;

export interface WebhookFetchMessageOptions {
cache?: boolean;
threadId?: Snowflake;
}

export interface WebhookMessageOptions extends Omit<MessageOptions, 'reply'> {
username?: string;
avatarURL?: string;
Expand Down

0 comments on commit 107822d

Please sign in to comment.