Skip to content

Commit f337065

Browse files
committed
Add support for interaction callback response body
1 parent 9bc5d6d commit f337065

File tree

8 files changed

+148
-40
lines changed

8 files changed

+148
-40
lines changed

lib/routes/Interactions.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
/** @module REST/Interactions */
2-
import type { EditInteractionContent, InteractionContent, InteractionResponse } from "../types/interactions";
2+
import type {
3+
EditInteractionContent,
4+
InteractionCallbackResponse,
5+
InteractionContent,
6+
InteractionResponse,
7+
RawInteractionCallbackResponse
8+
} from "../types/interactions";
39
import type { ExecuteWebhookWaitOptions } from "../types/webhooks";
410
import * as Routes from "../util/Routes";
511
import { InteractionResponseTypes } from "../Constants";
612
import type RESTManager from "../rest/RESTManager";
713
import type Message from "../structures/Message";
8-
import type { AnyTextableChannel } from "../types/channels";
14+
import type { AnyInteractionChannel, AnyTextableChannel } from "../types/channels";
915
import type { Uncached } from "../types/shared";
1016

1117
/** Various methods for interacting with interactions. Located at {@link Client#rest | Client#rest}{@link RESTManager#interactions | .interactions}. */
@@ -33,7 +39,7 @@ export default class Interactions {
3339
* @param options The options for creating the interaction response.
3440
* @caching This method **does not** cache its result.
3541
*/
36-
async createInteractionResponse(interactionID: string, interactionToken: string, options: InteractionResponse): Promise<void> {
42+
async createInteractionResponse<CH extends AnyInteractionChannel | Uncached = AnyInteractionChannel | Uncached>(interactionID: string, interactionToken: string, options: InteractionResponse): Promise<InteractionCallbackResponse<CH>> {
3743
let data: unknown;
3844
switch (options.type) {
3945
case InteractionResponseTypes.PONG:
@@ -88,15 +94,29 @@ export default class Interactions {
8894
break;
8995
}
9096
}
91-
await this._manager.authRequest<null>({
97+
return this._manager.authRequest<RawInteractionCallbackResponse>({
9298
method: "POST",
9399
path: Routes.INTERACTION_CALLBACK(interactionID, interactionToken),
94100
route: "/interactions/:id/:token/callback",
95101
json: {
96102
data,
97103
type: options.type
98104
}
99-
});
105+
}).then(d => ({
106+
interaction: {
107+
activityInstanceID: d.interaction.activity_instance_id,
108+
id: d.interaction.id,
109+
responseMessageEphemeral: d.interaction.response_message_ephemeral,
110+
responseMessageID: d.interaction.response_message_id,
111+
responseMessageLoading: d.interaction.response_message_loading,
112+
type: d.interaction.type
113+
},
114+
resource: d.resource ? {
115+
type: d.resource.type,
116+
activityInstance: d.resource.activity_instance,
117+
message: d.resource.message ? this._manager.client.util.updateMessage(d.resource.message) : undefined
118+
} : undefined
119+
}));
100120
}
101121

102122
/**

lib/structures/AutocompleteInteraction.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type {
1313
AuthorizingIntegrationOwners,
1414
AutocompleteChoice,
1515
AutocompleteInteractionData,
16+
InteractionCallbackResponse,
1617
InteractionGuild,
1718
RawAutocompleteInteraction
1819
} from "../types/interactions";
@@ -110,7 +111,7 @@ export default class AutocompleteInteraction<T extends AnyInteractionChannel | U
110111
* Acknowledge this interaction with a set of choices. This is an initial response, and more than one initial response cannot be used.
111112
* @param choices The choices to send.
112113
*/
113-
async result(choices: Array<AutocompleteChoice>): Promise<void> {
114+
async result(choices: Array<AutocompleteChoice>): Promise<InteractionCallbackResponse> {
114115
if (this.acknowledged) {
115116
throw new TypeError("Interactions cannot have more than one initial response.");
116117
}

lib/structures/CommandInteraction.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import type {
2323
InitialInteractionContent,
2424
InteractionGuild,
2525
AuthorizingIntegrationOwners,
26-
EditInteractionContent
26+
EditInteractionContent,
27+
InteractionCallbackResponse
2728
} from "../types/interactions";
2829
import type Client from "../Client";
2930
import type { RawMember } from "../types/guilds";
@@ -177,7 +178,7 @@ export default class CommandInteraction<T extends AnyInteractionChannel | Uncach
177178
*/
178179
async createFollowup(options: InteractionContent): Promise<FollowupMessageInteractionResponse<this>> {
179180
const message = await this.client.rest.interactions.createFollowupMessage<T>(this.applicationID, this.token, options);
180-
return new MessageInteractionResponse<CommandInteraction<T>>(this, message, "followup") as FollowupMessageInteractionResponse<this>;
181+
return new MessageInteractionResponse<CommandInteraction<T>>(this, message, "followup", null) as FollowupMessageInteractionResponse<this>;
181182
}
182183

183184
/**
@@ -195,15 +196,15 @@ export default class CommandInteraction<T extends AnyInteractionChannel | Uncach
195196
this.client.emit("warn", "You cannot attach files in an initial response. Defer the interaction, then use createFollowup.");
196197
}
197198
this.acknowledged = true;
198-
await this.client.rest.interactions.createInteractionResponse(this.id, this.token, { type: InteractionResponseTypes.CHANNEL_MESSAGE_WITH_SOURCE, data: options });
199-
return new MessageInteractionResponse<this>(this, null, "initial") as InitialMessagedInteractionResponse<this>;
199+
const cb = await this.client.rest.interactions.createInteractionResponse(this.id, this.token, { type: InteractionResponseTypes.CHANNEL_MESSAGE_WITH_SOURCE, data: options });
200+
return new MessageInteractionResponse<this>(this, null, "initial", cb) as InitialMessagedInteractionResponse<this>;
200201
}
201202

202203
/**
203204
* Respond to this interaction with a modal. This is an initial response, and more than one initial response cannot be used.
204205
* @param options The options for the modal.
205206
*/
206-
async createModal(options: ModalData): Promise<void> {
207+
async createModal(options: ModalData): Promise<InteractionCallbackResponse<T>> {
207208
if (this.acknowledged) {
208209
throw new TypeError("Interactions cannot have more than one initial response.");
209210
}
@@ -215,7 +216,7 @@ export default class CommandInteraction<T extends AnyInteractionChannel | Uncach
215216
* Defer this interaction. This is an initial response, and more than one initial response cannot be used.
216217
* @param flags The [flags](https://discord.com/developers/docs/resources/channel#message-object-message-flags) to respond with.
217218
*/
218-
async defer(flags?: number): Promise<void> {
219+
async defer(flags?: number): Promise<InteractionCallbackResponse<T>> {
219220
if (this.acknowledged) {
220221
throw new TypeError("Interactions cannot have more than one initial response.");
221222
}
@@ -303,7 +304,7 @@ export default class CommandInteraction<T extends AnyInteractionChannel | Uncach
303304
/**
304305
* Launch the bot's activity. This is an initial response, and more than one initial response cannot be used.
305306
*/
306-
async launchActivity(): Promise<void> {
307+
async launchActivity(): Promise<InteractionCallbackResponse<T>> {
307308
if (this.acknowledged) {
308309
throw new TypeError("Interactions cannot have more than one initial response.");
309310
}
@@ -316,7 +317,7 @@ export default class CommandInteraction<T extends AnyInteractionChannel | Uncach
316317
* Show a "premium required" response to the user. This is an initial response, and more than one initial response cannot be used.
317318
* @deprecated The {@link Constants~InteractionResponseTypes.PREMIUM_REQUIRED | PREMIUM_REQUIRED} interaction response type is now deprecated in favor of using {@link Types/Channels~PremiumButton | custom premium buttons}.
318319
*/
319-
async premiumRequired(): Promise<void> {
320+
async premiumRequired(): Promise<InteractionCallbackResponse<T>> {
320321
if (this.acknowledged) {
321322
throw new TypeError("Interactions cannot have more than one initial response.");
322323
}

lib/structures/ComponentInteraction.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
AuthorizingIntegrationOwners,
1717
EditInteractionContent,
1818
InitialInteractionContent,
19+
InteractionCallbackResponse,
1920
InteractionContent,
2021
InteractionGuild,
2122
MessageComponentButtonInteractionData,
@@ -178,7 +179,7 @@ export default class ComponentInteraction<V extends ComponentTypes.BUTTON | Sele
178179
*/
179180
async createFollowup(options: InteractionContent): Promise<FollowupMessageInteractionResponse<this>> {
180181
const message = await this.client.rest.interactions.createFollowupMessage<T>(this.applicationID, this.token, options);
181-
return new MessageInteractionResponse<ComponentInteraction<V, T>>(this, message, "followup") as FollowupMessageInteractionResponse<this>;
182+
return new MessageInteractionResponse<ComponentInteraction<V, T>>(this, message, "followup", null) as FollowupMessageInteractionResponse<this>;
182183
}
183184

184185
/**
@@ -196,15 +197,15 @@ export default class ComponentInteraction<V extends ComponentTypes.BUTTON | Sele
196197
this.client.emit("warn", "You cannot attach files in an initial response. Defer the interaction, then use createFollowup.");
197198
}
198199
this.acknowledged = true;
199-
await this.client.rest.interactions.createInteractionResponse(this.id, this.token, { type: InteractionResponseTypes.CHANNEL_MESSAGE_WITH_SOURCE, data: options });
200-
return new MessageInteractionResponse<this>(this, null, "initial") as InitialMessagedInteractionResponse<this>;
200+
const cb = await this.client.rest.interactions.createInteractionResponse(this.id, this.token, { type: InteractionResponseTypes.CHANNEL_MESSAGE_WITH_SOURCE, data: options });
201+
return new MessageInteractionResponse<this>(this, null, "initial", cb) as InitialMessagedInteractionResponse<this>;
201202
}
202203

203204
/**
204205
* Respond to this interaction with a modal. This is an initial response, and more than one initial response cannot be used.
205206
* @param options The options for the modal.
206207
*/
207-
async createModal(options: ModalData): Promise<void> {
208+
async createModal(options: ModalData): Promise<InteractionCallbackResponse<T>> {
208209
if (this.acknowledged) {
209210
throw new TypeError("Interactions cannot have more than one initial response.");
210211
}
@@ -216,7 +217,7 @@ export default class ComponentInteraction<V extends ComponentTypes.BUTTON | Sele
216217
* Defer this interaction with a `DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE` response. This is an initial response, and more than one initial response cannot be used.
217218
* @param flags The [flags](https://discord.com/developers/docs/resources/channel#message-object-message-flags) to respond with.
218219
*/
219-
async defer(flags?: number): Promise<void> {
220+
async defer(flags?: number): Promise<InteractionCallbackResponse<T>> {
220221
if (this.acknowledged) {
221222
throw new TypeError("Interactions cannot have more than one initial response.");
222223
}
@@ -228,7 +229,7 @@ export default class ComponentInteraction<V extends ComponentTypes.BUTTON | Sele
228229
* Defer this interaction with a `DEFERRED_UPDATE_MESSAGE` response. This is an initial response, and more than one initial response cannot be used.
229230
* @param flags The [flags](https://discord.com/developers/docs/resources/channel#message-object-message-flags) to respond with.
230231
*/
231-
async deferUpdate(flags?: number): Promise<void> {
232+
async deferUpdate(flags?: number): Promise<InteractionCallbackResponse<T>> {
232233
if (this.acknowledged) {
233234
throw new TypeError("Interactions cannot have more than one initial response.");
234235
}
@@ -272,7 +273,7 @@ export default class ComponentInteraction<V extends ComponentTypes.BUTTON | Sele
272273
* Edit the message this interaction is from. If this interaction has already been acknowledged, use `editOriginal`.
273274
* @param options The options for editing the message.
274275
*/
275-
async editParent(options: InteractionContent): Promise<void> {
276+
async editParent(options: InteractionContent): Promise<InteractionCallbackResponse<T>> {
276277
if (this.acknowledged) {
277278
throw new TypeError("Interactions cannot have more than one initial response.");
278279
}
@@ -319,17 +320,29 @@ export default class ComponentInteraction<V extends ComponentTypes.BUTTON | Sele
319320
|| this.data.componentType === ComponentTypes.USER_SELECT;
320321
}
321322

323+
/**
324+
* Launch the bot's activity. This is an initial response, and more than one initial response cannot be used.
325+
*/
326+
async launchActivity(): Promise<InteractionCallbackResponse<T>> {
327+
if (this.acknowledged) {
328+
throw new TypeError("Interactions cannot have more than one initial response.");
329+
}
330+
331+
this.acknowledged = true;
332+
return this.client.rest.interactions.createInteractionResponse(this.id, this.token, { type: InteractionResponseTypes.LAUNCH_ACTIVITY });
333+
}
334+
322335
/**
323336
* Show a "premium required" response to the user. This is an initial response, and more than one initial response cannot be used.
324337
* @deprecated The {@link Constants~InteractionResponseTypes.PREMIUM_REQUIRED | PREMIUM_REQUIRED} interaction response type is now deprecated in favor of using {@link Types/Channels~PremiumButton | custom premium buttons}.
325338
*/
326-
async premiumRequired(): Promise<void> {
339+
async premiumRequired(): Promise<InteractionCallbackResponse<T>> {
327340
if (this.acknowledged) {
328341
throw new TypeError("Interactions cannot have more than one initial response.");
329342
}
330343

331344
this.acknowledged = true;
332-
return this.client.rest.interactions.createInteractionResponse(this.id, this.token, { type: InteractionResponseTypes.PREMIUM_REQUIRED, data: {} });
345+
return this.client.rest.interactions.createInteractionResponse(this.id, this.token, { type: InteractionResponseTypes.PREMIUM_REQUIRED });
333346
}
334347

335348
/**

lib/structures/ModalSubmitInteraction.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
AuthorizingIntegrationOwners,
1515
EditInteractionContent,
1616
InitialInteractionContent,
17+
InteractionCallbackResponse,
1718
InteractionContent,
1819
InteractionGuild,
1920
ModalSubmitInteractionData,
@@ -120,7 +121,7 @@ export default class ModalSubmitInteraction<T extends AnyInteractionChannel | Un
120121
*/
121122
async createFollowup(options: InteractionContent): Promise<FollowupMessageInteractionResponse<this>> {
122123
const message = await this.client.rest.interactions.createFollowupMessage<T>(this.applicationID, this.token, options);
123-
return new MessageInteractionResponse<ModalSubmitInteraction<T>>(this, message, "followup") as FollowupMessageInteractionResponse<this>;
124+
return new MessageInteractionResponse<ModalSubmitInteraction<T>>(this, message, "followup", null) as FollowupMessageInteractionResponse<this>;
124125
}
125126

126127
/**
@@ -138,15 +139,15 @@ export default class ModalSubmitInteraction<T extends AnyInteractionChannel | Un
138139
this.client.emit("warn", "You cannot attach files in an initial response. Defer the interaction, then use createFollowup.");
139140
}
140141
this.acknowledged = true;
141-
await this.client.rest.interactions.createInteractionResponse(this.id, this.token, { type: InteractionResponseTypes.CHANNEL_MESSAGE_WITH_SOURCE, data: options });
142-
return new MessageInteractionResponse<this>(this, null, "initial") as InitialMessagedInteractionResponse<this>;
142+
const cb = await this.client.rest.interactions.createInteractionResponse(this.id, this.token, { type: InteractionResponseTypes.CHANNEL_MESSAGE_WITH_SOURCE, data: options });
143+
return new MessageInteractionResponse<this>(this, null, "initial", cb) as InitialMessagedInteractionResponse<this>;
143144
}
144145

145146
/**
146147
* Defer this interaction. This is an initial response, and more than one initial response cannot be used.
147148
* @param flags The [flags](https://discord.com/developers/docs/resources/channel#message-object-message-flags) to respond with.
148149
*/
149-
async defer(flags?: number): Promise<void> {
150+
async defer(flags?: number): Promise<InteractionCallbackResponse<T>> {
150151
if (this.acknowledged) {
151152
throw new TypeError("Interactions cannot have more than one initial response.");
152153
}
@@ -158,7 +159,7 @@ export default class ModalSubmitInteraction<T extends AnyInteractionChannel | Un
158159
* Defer this interaction with a `DEFERRED_UPDATE_MESSAGE` response. This is an initial response, and more than one initial response cannot be used.
159160
* @param flags The [flags](https://discord.com/developers/docs/resources/channel#message-object-message-flags) to respond with.
160161
*/
161-
async deferUpdate(flags?: number): Promise<void> {
162+
async deferUpdate(flags?: number): Promise<InteractionCallbackResponse<T>> {
162163
if (this.acknowledged) {
163164
throw new TypeError("Interactions cannot have more than one initial response.");
164165
}
@@ -202,7 +203,7 @@ export default class ModalSubmitInteraction<T extends AnyInteractionChannel | Un
202203
* Edit the message this interaction is from. If this interaction has already been acknowledged, use `createFollowup`.
203204
* @param options The options for editing the message.
204205
*/
205-
async editParent(options: InteractionContent): Promise<void> {
206+
async editParent(options: InteractionContent): Promise<InteractionCallbackResponse<T>> {
206207
if (this.acknowledged) {
207208
throw new TypeError("Interactions cannot have more than one initial response.");
208209
}
@@ -235,17 +236,29 @@ export default class ModalSubmitInteraction<T extends AnyInteractionChannel | Un
235236
return this.guildID === null;
236237
}
237238

239+
/**
240+
* Launch the bot's activity. This is an initial response, and more than one initial response cannot be used.
241+
*/
242+
async launchActivity(): Promise<InteractionCallbackResponse<T>> {
243+
if (this.acknowledged) {
244+
throw new TypeError("Interactions cannot have more than one initial response.");
245+
}
246+
247+
this.acknowledged = true;
248+
return this.client.rest.interactions.createInteractionResponse(this.id, this.token, { type: InteractionResponseTypes.LAUNCH_ACTIVITY });
249+
}
250+
238251
/**
239252
* Show a "premium required" response to the user. This is an initial response, and more than one initial response cannot be used.
240253
* @deprecated The {@link Constants~InteractionResponseTypes.PREMIUM_REQUIRED | PREMIUM_REQUIRED} interaction response type is now deprecated in favor of using {@link Types/Channels~PremiumButton | custom premium buttons}.
241254
*/
242-
async premiumRequired(): Promise<void> {
255+
async premiumRequired(): Promise<InteractionCallbackResponse<T>> {
243256
if (this.acknowledged) {
244257
throw new TypeError("Interactions cannot have more than one initial response.");
245258
}
246259

247260
this.acknowledged = true;
248-
return this.client.rest.interactions.createInteractionResponse(this.id, this.token, { type: InteractionResponseTypes.PREMIUM_REQUIRED, data: {} });
261+
return this.client.rest.interactions.createInteractionResponse(this.id, this.token, { type: InteractionResponseTypes.PREMIUM_REQUIRED });
249262
}
250263

251264
/**

lib/structures/PingInteraction.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** @module PingInteraction */
22
import Interaction from "./Interaction";
33
import { InteractionResponseTypes, type InteractionTypes } from "../Constants";
4-
import type { RawPingInteraction } from "../types/interactions";
4+
import type { InteractionCallbackResponse, RawPingInteraction } from "../types/interactions";
55
import type Client from "../Client";
66
import type { JSONPingInteraction } from "../types/json";
77

@@ -15,7 +15,7 @@ export default class PingInteraction extends Interaction {
1515
/**
1616
* Responds to the interaction with a `PONG`.
1717
*/
18-
async pong(): Promise<void> {
18+
async pong(): Promise<InteractionCallbackResponse> {
1919
return this.client.rest.interactions.createInteractionResponse(this.id, this.token, { type: InteractionResponseTypes.PONG });
2020
}
2121

0 commit comments

Comments
 (0)