Skip to content

Commit 8469fb3

Browse files
monbreykodiakhq[bot]
authored andcommitted
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>
1 parent d25ef43 commit 8469fb3

File tree

1 file changed

+196
-15
lines changed

1 file changed

+196
-15
lines changed

packages/core/src/api/interactions.ts

Lines changed: 196 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable jsdoc/check-param-names */
22

3-
import type { RawFile, RequestData, REST } from '@discordjs/rest';
3+
import { makeURLSearchParams, type RawFile, type RequestData, type REST } from '@discordjs/rest';
44
import {
55
InteractionResponseType,
66
Routes,
@@ -10,6 +10,8 @@ import {
1010
type APIModalInteractionResponseCallbackData,
1111
type APIPremiumRequiredInteractionResponse,
1212
type RESTGetAPIWebhookWithTokenMessageResult,
13+
type RESTPostAPIInteractionCallbackQuery,
14+
type RESTPostAPIInteractionCallbackWithResponseResult,
1315
type Snowflake,
1416
} from 'discord-api-types/v10';
1517
import type { WebhooksAPI } from './webhook.js';
@@ -20,6 +22,23 @@ export class InteractionsAPI {
2022
private readonly webhooks: WebhooksAPI,
2123
) {}
2224

25+
/**
26+
* Replies to an interaction and returns an interaction callback object
27+
*
28+
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
29+
* @param interactionId - The id of the interaction
30+
* @param interactionToken - The token of the interaction
31+
* @param body - The callback data for replying
32+
* @param options - The options for replying
33+
*/
34+
public async reply(
35+
interactionId: Snowflake,
36+
interactionToken: string,
37+
body: APIInteractionResponseCallbackData &
38+
RESTPostAPIInteractionCallbackQuery & { files?: RawFile[]; with_response: true },
39+
options?: Pick<RequestData, 'signal'>,
40+
): Promise<RESTPostAPIInteractionCallbackWithResponseResult>;
41+
2342
/**
2443
* Replies to an interaction
2544
*
@@ -32,10 +51,23 @@ export class InteractionsAPI {
3251
public async reply(
3352
interactionId: Snowflake,
3453
interactionToken: string,
35-
{ files, ...data }: APIInteractionResponseCallbackData & { files?: RawFile[] },
54+
body: APIInteractionResponseCallbackData &
55+
RESTPostAPIInteractionCallbackQuery & { files?: RawFile[]; with_response?: false },
56+
options?: Pick<RequestData, 'signal'>,
57+
): Promise<undefined>;
58+
59+
public async reply(
60+
interactionId: Snowflake,
61+
interactionToken: string,
62+
{
63+
files,
64+
with_response,
65+
...data
66+
}: APIInteractionResponseCallbackData & RESTPostAPIInteractionCallbackQuery & { files?: RawFile[] },
3667
{ signal }: Pick<RequestData, 'signal'> = {},
3768
) {
38-
await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
69+
const response = await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
70+
query: makeURLSearchParams({ with_response }),
3971
files,
4072
auth: false,
4173
body: {
@@ -44,53 +76,114 @@ export class InteractionsAPI {
4476
},
4577
signal,
4678
});
79+
80+
return with_response ? response : undefined;
4781
}
4882

83+
/**
84+
* Defers the reply to an interaction and returns an interaction callback object
85+
*
86+
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
87+
* @param interactionId - The id of the interaction
88+
* @param interactionToken - The token of the interaction
89+
* @param body - The callback data for deferring the reply
90+
* @param options - The options for deferring
91+
*/
92+
public async defer(
93+
interactionId: Snowflake,
94+
interactionToken: string,
95+
body: APIInteractionResponseDeferredChannelMessageWithSource['data'] &
96+
RESTPostAPIInteractionCallbackQuery & { with_response: true },
97+
options?: Pick<RequestData, 'signal'>,
98+
): Promise<RESTPostAPIInteractionCallbackWithResponseResult>;
99+
49100
/**
50101
* Defers the reply to an interaction
51102
*
52103
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
53104
* @param interactionId - The id of the interaction
54105
* @param interactionToken - The token of the interaction
55-
* @param data - The data for deferring the reply
106+
* @param body - The callback data for deferring the reply
56107
* @param options - The options for deferring
57108
*/
58109
public async defer(
59110
interactionId: Snowflake,
60111
interactionToken: string,
61-
data?: APIInteractionResponseDeferredChannelMessageWithSource['data'],
112+
body?: APIInteractionResponseDeferredChannelMessageWithSource['data'] &
113+
RESTPostAPIInteractionCallbackQuery & { with_response?: false },
114+
options?: Pick<RequestData, 'signal'>,
115+
): Promise<undefined>;
116+
117+
public async defer(
118+
interactionId: Snowflake,
119+
interactionToken: string,
120+
{
121+
with_response,
122+
...data
123+
}: APIInteractionResponseDeferredChannelMessageWithSource['data'] & RESTPostAPIInteractionCallbackQuery = {},
62124
{ signal }: Pick<RequestData, 'signal'> = {},
63125
) {
64-
await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
126+
const response = await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
127+
query: makeURLSearchParams({ with_response }),
65128
auth: false,
66129
body: {
67130
type: InteractionResponseType.DeferredChannelMessageWithSource,
68131
data,
69132
},
70133
signal,
71134
});
135+
136+
return with_response ? response : undefined;
72137
}
73138

139+
/**
140+
* Defers an update from a message component interaction and returns an interaction callback object
141+
*
142+
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
143+
* @param interactionId - The id of the interaction
144+
* @param interactionToken - The token of the interaction
145+
* @param body - The callback data for deferring the update
146+
* @param options - The options for deferring
147+
*/
148+
public async deferMessageUpdate(
149+
interactionId: Snowflake,
150+
interactionToken: string,
151+
body: RESTPostAPIInteractionCallbackQuery & { with_response: true },
152+
options?: Pick<RequestData, 'signal'>,
153+
): Promise<undefined>;
154+
74155
/**
75156
* Defers an update from a message component interaction
76157
*
77158
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
78159
* @param interactionId - The id of the interaction
79160
* @param interactionToken - The token of the interaction
161+
* @param body - The callback data for deferring the update
80162
* @param options - The options for deferring
81163
*/
82164
public async deferMessageUpdate(
83165
interactionId: Snowflake,
84166
interactionToken: string,
167+
body?: RESTPostAPIInteractionCallbackQuery & { with_response?: false },
168+
options?: Pick<RequestData, 'signal'>,
169+
): Promise<RESTPostAPIInteractionCallbackWithResponseResult>;
170+
171+
public async deferMessageUpdate(
172+
interactionId: Snowflake,
173+
interactionToken: string,
174+
{ with_response }: RESTPostAPIInteractionCallbackQuery = {},
85175
{ signal }: Pick<RequestData, 'signal'> = {},
86176
) {
87-
await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
177+
const response = await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
178+
query: makeURLSearchParams({ with_response }),
88179
auth: false,
89180
body: {
90181
type: InteractionResponseType.DeferredMessageUpdate,
91182
},
92183
signal,
93184
});
185+
186+
return with_response ? response : undefined;
94187
}
95188

96189
/**
@@ -175,6 +268,23 @@ export class InteractionsAPI {
175268
await this.webhooks.deleteMessage(applicationId, interactionToken, messageId ?? '@original', {}, { signal });
176269
}
177270

271+
/**
272+
* Updates the message the component interaction was triggered on and returns an interaction callback object
273+
*
274+
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
275+
* @param interactionId - The id of the interaction
276+
* @param interactionToken - The token of the interaction
277+
* @param callbackData - The callback data for updating the interaction
278+
* @param options - The options for updating the interaction
279+
*/
280+
public async updateMessage(
281+
interactionId: Snowflake,
282+
interactionToken: string,
283+
callbackData: APIInteractionResponseCallbackData &
284+
RESTPostAPIInteractionCallbackQuery & { files?: RawFile[]; with_response: true },
285+
options: Pick<RequestData, 'signal'>,
286+
): Promise<RESTPostAPIInteractionCallbackWithResponseResult>;
287+
178288
/**
179289
* Updates the message the component interaction was triggered on
180290
*
@@ -187,10 +297,22 @@ export class InteractionsAPI {
187297
public async updateMessage(
188298
interactionId: Snowflake,
189299
interactionToken: string,
190-
{ files, ...data }: APIInteractionResponseCallbackData & { files?: RawFile[] },
300+
callbackData: APIInteractionResponseCallbackData &
301+
RESTPostAPIInteractionCallbackQuery & { files?: RawFile[]; with_response?: false },
302+
options: Pick<RequestData, 'signal'>,
303+
): Promise<undefined>;
304+
305+
public async updateMessage(
306+
interactionId: Snowflake,
307+
interactionToken: string,
308+
{
309+
files,
310+
with_response,
311+
...data
312+
}: APIInteractionResponseCallbackData & RESTPostAPIInteractionCallbackQuery & { files?: RawFile[] },
191313
{ signal }: Pick<RequestData, 'signal'> = {},
192314
) {
193-
await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
315+
const response = await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
194316
files,
195317
auth: false,
196318
body: {
@@ -199,8 +321,27 @@ export class InteractionsAPI {
199321
},
200322
signal,
201323
});
324+
325+
return with_response ? response : undefined;
202326
}
203327

328+
/**
329+
* Sends an autocomplete response to an interaction and returns an interaction callback object
330+
*
331+
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
332+
* @param interactionId - The id of the interaction
333+
* @param interactionToken - The token of the interaction
334+
* @param callbackData - The callback data for the autocomplete response
335+
* @param options - The options for sending the autocomplete response
336+
*/
337+
public async createAutocompleteResponse(
338+
interactionId: Snowflake,
339+
interactionToken: string,
340+
callbackData: APICommandAutocompleteInteractionResponseCallbackData &
341+
RESTPostAPIInteractionCallbackQuery & { with_response: true },
342+
options?: Pick<RequestData, 'signal'>,
343+
): Promise<APICommandAutocompleteInteractionResponseCallbackData>;
344+
204345
/**
205346
* Sends an autocomplete response to an interaction
206347
*
@@ -213,19 +354,49 @@ export class InteractionsAPI {
213354
public async createAutocompleteResponse(
214355
interactionId: Snowflake,
215356
interactionToken: string,
216-
callbackData: APICommandAutocompleteInteractionResponseCallbackData,
357+
callbackData: APICommandAutocompleteInteractionResponseCallbackData &
358+
RESTPostAPIInteractionCallbackQuery & { with_response?: false },
359+
options: Pick<RequestData, 'signal'>,
360+
): Promise<undefined>;
361+
362+
public async createAutocompleteResponse(
363+
interactionId: Snowflake,
364+
interactionToken: string,
365+
{
366+
with_response,
367+
...data
368+
}: APICommandAutocompleteInteractionResponseCallbackData & RESTPostAPIInteractionCallbackQuery,
217369
{ signal }: Pick<RequestData, 'signal'> = {},
218370
) {
219-
await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
371+
const response = await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
220372
auth: false,
221373
body: {
222374
type: InteractionResponseType.ApplicationCommandAutocompleteResult,
223-
data: callbackData,
375+
data,
224376
},
225377
signal,
226378
});
379+
380+
return with_response ? response : undefined;
227381
}
228382

383+
/**
384+
* Sends a modal response to an interaction and returns an interaction callback object
385+
*
386+
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response}
387+
* @param interactionId - The id of the interaction
388+
* @param interactionToken - The token of the interaction
389+
* @param callbackData - The modal callback data to send
390+
* @param options - The options for sending the modal
391+
*/
392+
public async createModal(
393+
interactionId: Snowflake,
394+
interactionToken: string,
395+
callbackData: APIModalInteractionResponseCallbackData &
396+
RESTPostAPIInteractionCallbackQuery & { with_response: true },
397+
options?: Pick<RequestData, 'signal'>,
398+
): Promise<RESTPostAPIInteractionCallbackWithResponseResult>;
399+
229400
/**
230401
* Sends a modal response to an interaction
231402
*
@@ -238,17 +409,27 @@ export class InteractionsAPI {
238409
public async createModal(
239410
interactionId: Snowflake,
240411
interactionToken: string,
241-
callbackData: APIModalInteractionResponseCallbackData,
412+
callbackData: APIModalInteractionResponseCallbackData &
413+
RESTPostAPIInteractionCallbackQuery & { with_response?: false },
414+
options?: Pick<RequestData, 'signal'>,
415+
): Promise<undefined>;
416+
417+
public async createModal(
418+
interactionId: Snowflake,
419+
interactionToken: string,
420+
{ with_response, ...data }: APIModalInteractionResponseCallbackData & RESTPostAPIInteractionCallbackQuery,
242421
{ signal }: Pick<RequestData, 'signal'> = {},
243422
) {
244-
await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
423+
const response = await this.rest.post(Routes.interactionCallback(interactionId, interactionToken), {
245424
auth: false,
246425
body: {
247426
type: InteractionResponseType.Modal,
248-
data: callbackData,
427+
data,
249428
},
250429
signal,
251430
});
431+
432+
return with_response ? response : undefined;
252433
}
253434

254435
/**

0 commit comments

Comments
 (0)