feat(interactions): support with_response query parameter in core (#10512)

* feat(interactions): support with_response query parameter

* fix: address feedback from comments

* chore: remove extraneous documentation

* fix: return type is now undefined

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
Ryan Munro
2024-11-18 09:48:30 +11:00
committed by Jiralite
parent d25ef434ae
commit 8469fb3bad

View File

@@ -1,6 +1,6 @@
/* eslint-disable jsdoc/check-param-names */ /* eslint-disable jsdoc/check-param-names */
import type { RawFile, RequestData, REST } from '@discordjs/rest'; import { makeURLSearchParams, type RawFile, type RequestData, type REST } from '@discordjs/rest';
import { import {
InteractionResponseType, InteractionResponseType,
Routes, Routes,
@@ -10,6 +10,8 @@ import {
type APIModalInteractionResponseCallbackData, type APIModalInteractionResponseCallbackData,
type APIPremiumRequiredInteractionResponse, type APIPremiumRequiredInteractionResponse,
type RESTGetAPIWebhookWithTokenMessageResult, type RESTGetAPIWebhookWithTokenMessageResult,
type RESTPostAPIInteractionCallbackQuery,
type RESTPostAPIInteractionCallbackWithResponseResult,
type Snowflake, type Snowflake,
} from 'discord-api-types/v10'; } from 'discord-api-types/v10';
import type { WebhooksAPI } from './webhook.js'; import type { WebhooksAPI } from './webhook.js';
@@ -20,6 +22,23 @@ export class InteractionsAPI {
private readonly webhooks: WebhooksAPI, private readonly webhooks: WebhooksAPI,
) {} ) {}
/**
* Replies to an interaction and returns an interaction callback object
*
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
* @param interactionId - The id of the interaction
* @param interactionToken - The token of the interaction
* @param body - The callback data for replying
* @param options - The options for replying
*/
public async reply(
interactionId: Snowflake,
interactionToken: string,
body: APIInteractionResponseCallbackData &
RESTPostAPIInteractionCallbackQuery & { files?: RawFile[]; with_response: true },
options?: Pick<RequestData, 'signal'>,
): Promise<RESTPostAPIInteractionCallbackWithResponseResult>;
/** /**
* Replies to an interaction * Replies to an interaction
* *
@@ -32,10 +51,23 @@ export class InteractionsAPI {
public async reply( public async reply(
interactionId: Snowflake, interactionId: Snowflake,
interactionToken: string, interactionToken: string,
{ files, ...data }: APIInteractionResponseCallbackData & { files?: RawFile[] }, body: APIInteractionResponseCallbackData &
RESTPostAPIInteractionCallbackQuery & { files?: RawFile[]; with_response?: false },
options?: Pick<RequestData, 'signal'>,
): Promise<undefined>;
public async reply(
interactionId: Snowflake,
interactionToken: string,
{
files,
with_response,
...data
}: APIInteractionResponseCallbackData & RESTPostAPIInteractionCallbackQuery & { files?: RawFile[] },
{ signal }: Pick<RequestData, 'signal'> = {}, { signal }: Pick<RequestData, 'signal'> = {},
) { ) {
await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), { const response = await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
query: makeURLSearchParams({ with_response }),
files, files,
auth: false, auth: false,
body: { body: {
@@ -44,24 +76,55 @@ export class InteractionsAPI {
}, },
signal, signal,
}); });
return with_response ? response : undefined;
} }
/**
* Defers the reply to an interaction and returns an interaction callback object
*
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
* @param interactionId - The id of the interaction
* @param interactionToken - The token of the interaction
* @param body - The callback data for deferring the reply
* @param options - The options for deferring
*/
public async defer(
interactionId: Snowflake,
interactionToken: string,
body: APIInteractionResponseDeferredChannelMessageWithSource['data'] &
RESTPostAPIInteractionCallbackQuery & { with_response: true },
options?: Pick<RequestData, 'signal'>,
): Promise<RESTPostAPIInteractionCallbackWithResponseResult>;
/** /**
* Defers the reply to an interaction * Defers the reply to an interaction
* *
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response} * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
* @param interactionId - The id of the interaction * @param interactionId - The id of the interaction
* @param interactionToken - The token of the interaction * @param interactionToken - The token of the interaction
* @param data - The data for deferring the reply * @param body - The callback data for deferring the reply
* @param options - The options for deferring * @param options - The options for deferring
*/ */
public async defer( public async defer(
interactionId: Snowflake, interactionId: Snowflake,
interactionToken: string, interactionToken: string,
data?: APIInteractionResponseDeferredChannelMessageWithSource['data'], body?: APIInteractionResponseDeferredChannelMessageWithSource['data'] &
RESTPostAPIInteractionCallbackQuery & { with_response?: false },
options?: Pick<RequestData, 'signal'>,
): Promise<undefined>;
public async defer(
interactionId: Snowflake,
interactionToken: string,
{
with_response,
...data
}: APIInteractionResponseDeferredChannelMessageWithSource['data'] & RESTPostAPIInteractionCallbackQuery = {},
{ signal }: Pick<RequestData, 'signal'> = {}, { signal }: Pick<RequestData, 'signal'> = {},
) { ) {
await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), { const response = await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
query: makeURLSearchParams({ with_response }),
auth: false, auth: false,
body: { body: {
type: InteractionResponseType.DeferredChannelMessageWithSource, type: InteractionResponseType.DeferredChannelMessageWithSource,
@@ -69,28 +132,58 @@ export class InteractionsAPI {
}, },
signal, signal,
}); });
return with_response ? response : undefined;
} }
/**
* Defers an update from a message component interaction and returns an interaction callback object
*
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
* @param interactionId - The id of the interaction
* @param interactionToken - The token of the interaction
* @param body - The callback data for deferring the update
* @param options - The options for deferring
*/
public async deferMessageUpdate(
interactionId: Snowflake,
interactionToken: string,
body: RESTPostAPIInteractionCallbackQuery & { with_response: true },
options?: Pick<RequestData, 'signal'>,
): Promise<undefined>;
/** /**
* Defers an update from a message component interaction * Defers an update from a message component interaction
* *
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response} * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
* @param interactionId - The id of the interaction * @param interactionId - The id of the interaction
* @param interactionToken - The token of the interaction * @param interactionToken - The token of the interaction
* @param body - The callback data for deferring the update
* @param options - The options for deferring * @param options - The options for deferring
*/ */
public async deferMessageUpdate( public async deferMessageUpdate(
interactionId: Snowflake, interactionId: Snowflake,
interactionToken: string, interactionToken: string,
body?: RESTPostAPIInteractionCallbackQuery & { with_response?: false },
options?: Pick<RequestData, 'signal'>,
): Promise<RESTPostAPIInteractionCallbackWithResponseResult>;
public async deferMessageUpdate(
interactionId: Snowflake,
interactionToken: string,
{ with_response }: RESTPostAPIInteractionCallbackQuery = {},
{ signal }: Pick<RequestData, 'signal'> = {}, { signal }: Pick<RequestData, 'signal'> = {},
) { ) {
await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), { const response = await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
query: makeURLSearchParams({ with_response }),
auth: false, auth: false,
body: { body: {
type: InteractionResponseType.DeferredMessageUpdate, type: InteractionResponseType.DeferredMessageUpdate,
}, },
signal, signal,
}); });
return with_response ? response : undefined;
} }
/** /**
@@ -175,6 +268,23 @@ export class InteractionsAPI {
await this.webhooks.deleteMessage(applicationId, interactionToken, messageId ?? '@original', {}, { signal }); await this.webhooks.deleteMessage(applicationId, interactionToken, messageId ?? '@original', {}, { signal });
} }
/**
* Updates the message the component interaction was triggered on and returns an interaction callback object
*
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
* @param interactionId - The id of the interaction
* @param interactionToken - The token of the interaction
* @param callbackData - The callback data for updating the interaction
* @param options - The options for updating the interaction
*/
public async updateMessage(
interactionId: Snowflake,
interactionToken: string,
callbackData: APIInteractionResponseCallbackData &
RESTPostAPIInteractionCallbackQuery & { files?: RawFile[]; with_response: true },
options: Pick<RequestData, 'signal'>,
): Promise<RESTPostAPIInteractionCallbackWithResponseResult>;
/** /**
* Updates the message the component interaction was triggered on * Updates the message the component interaction was triggered on
* *
@@ -187,10 +297,22 @@ export class InteractionsAPI {
public async updateMessage( public async updateMessage(
interactionId: Snowflake, interactionId: Snowflake,
interactionToken: string, interactionToken: string,
{ files, ...data }: APIInteractionResponseCallbackData & { files?: RawFile[] }, callbackData: APIInteractionResponseCallbackData &
RESTPostAPIInteractionCallbackQuery & { files?: RawFile[]; with_response?: false },
options: Pick<RequestData, 'signal'>,
): Promise<undefined>;
public async updateMessage(
interactionId: Snowflake,
interactionToken: string,
{
files,
with_response,
...data
}: APIInteractionResponseCallbackData & RESTPostAPIInteractionCallbackQuery & { files?: RawFile[] },
{ signal }: Pick<RequestData, 'signal'> = {}, { signal }: Pick<RequestData, 'signal'> = {},
) { ) {
await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), { const response = await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
files, files,
auth: false, auth: false,
body: { body: {
@@ -199,8 +321,27 @@ export class InteractionsAPI {
}, },
signal, signal,
}); });
return with_response ? response : undefined;
} }
/**
* Sends an autocomplete response to an interaction and returns an interaction callback object
*
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
* @param interactionId - The id of the interaction
* @param interactionToken - The token of the interaction
* @param callbackData - The callback data for the autocomplete response
* @param options - The options for sending the autocomplete response
*/
public async createAutocompleteResponse(
interactionId: Snowflake,
interactionToken: string,
callbackData: APICommandAutocompleteInteractionResponseCallbackData &
RESTPostAPIInteractionCallbackQuery & { with_response: true },
options?: Pick<RequestData, 'signal'>,
): Promise<APICommandAutocompleteInteractionResponseCallbackData>;
/** /**
* Sends an autocomplete response to an interaction * Sends an autocomplete response to an interaction
* *
@@ -213,19 +354,49 @@ export class InteractionsAPI {
public async createAutocompleteResponse( public async createAutocompleteResponse(
interactionId: Snowflake, interactionId: Snowflake,
interactionToken: string, interactionToken: string,
callbackData: APICommandAutocompleteInteractionResponseCallbackData, callbackData: APICommandAutocompleteInteractionResponseCallbackData &
RESTPostAPIInteractionCallbackQuery & { with_response?: false },
options: Pick<RequestData, 'signal'>,
): Promise<undefined>;
public async createAutocompleteResponse(
interactionId: Snowflake,
interactionToken: string,
{
with_response,
...data
}: APICommandAutocompleteInteractionResponseCallbackData & RESTPostAPIInteractionCallbackQuery,
{ signal }: Pick<RequestData, 'signal'> = {}, { signal }: Pick<RequestData, 'signal'> = {},
) { ) {
await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), { const response = await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
auth: false, auth: false,
body: { body: {
type: InteractionResponseType.ApplicationCommandAutocompleteResult, type: InteractionResponseType.ApplicationCommandAutocompleteResult,
data: callbackData, data,
}, },
signal, signal,
}); });
return with_response ? response : undefined;
} }
/**
* Sends a modal response to an interaction and returns an interaction callback object
*
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
* @param interactionId - The id of the interaction
* @param interactionToken - The token of the interaction
* @param callbackData - The modal callback data to send
* @param options - The options for sending the modal
*/
public async createModal(
interactionId: Snowflake,
interactionToken: string,
callbackData: APIModalInteractionResponseCallbackData &
RESTPostAPIInteractionCallbackQuery & { with_response: true },
options?: Pick<RequestData, 'signal'>,
): Promise<RESTPostAPIInteractionCallbackWithResponseResult>;
/** /**
* Sends a modal response to an interaction * Sends a modal response to an interaction
* *
@@ -238,17 +409,27 @@ export class InteractionsAPI {
public async createModal( public async createModal(
interactionId: Snowflake, interactionId: Snowflake,
interactionToken: string, interactionToken: string,
callbackData: APIModalInteractionResponseCallbackData, callbackData: APIModalInteractionResponseCallbackData &
RESTPostAPIInteractionCallbackQuery & { with_response?: false },
options?: Pick<RequestData, 'signal'>,
): Promise<undefined>;
public async createModal(
interactionId: Snowflake,
interactionToken: string,
{ with_response, ...data }: APIModalInteractionResponseCallbackData & RESTPostAPIInteractionCallbackQuery,
{ signal }: Pick<RequestData, 'signal'> = {}, { signal }: Pick<RequestData, 'signal'> = {},
) { ) {
await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), { const response = await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
auth: false, auth: false,
body: { body: {
type: InteractionResponseType.Modal, type: InteractionResponseType.Modal,
data: callbackData, data,
}, },
signal, signal,
}); });
return with_response ? response : undefined;
} }
/** /**