@minesa-org/mini-interaction 0.2.8 → 0.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clients/MiniInteraction.js +6 -0
- package/dist/utils/CommandInteractionOptions.d.ts +1 -1
- package/dist/utils/CommandInteractionOptions.js +16 -2
- package/dist/utils/ContextMenuInteraction.d.ts +8 -0
- package/dist/utils/ContextMenuInteraction.js +20 -2
- package/dist/utils/MessageComponentInteraction.js +16 -0
- package/package.json +1 -1
|
@@ -1278,6 +1278,8 @@ export class MiniInteraction {
|
|
|
1278
1278
|
const interactionWithHelpers = createUserContextMenuInteraction(commandInteraction, {
|
|
1279
1279
|
onAck: (response) => ackResolver?.(response),
|
|
1280
1280
|
sendFollowUp,
|
|
1281
|
+
canRespond: (id) => this.canRespond(id),
|
|
1282
|
+
trackResponse: (id, token, state) => this.trackInteractionState(id, token, state),
|
|
1281
1283
|
});
|
|
1282
1284
|
response = await command.handler(interactionWithHelpers);
|
|
1283
1285
|
resolvedResponse =
|
|
@@ -1288,6 +1290,8 @@ export class MiniInteraction {
|
|
|
1288
1290
|
const interactionWithHelpers = createAppCommandInteraction(commandInteraction, {
|
|
1289
1291
|
onAck: (response) => ackResolver?.(response),
|
|
1290
1292
|
sendFollowUp,
|
|
1293
|
+
canRespond: (id) => this.canRespond(id),
|
|
1294
|
+
trackResponse: (id, token, state) => this.trackInteractionState(id, token, state),
|
|
1291
1295
|
});
|
|
1292
1296
|
response = await command.handler(interactionWithHelpers);
|
|
1293
1297
|
resolvedResponse =
|
|
@@ -1299,6 +1303,8 @@ export class MiniInteraction {
|
|
|
1299
1303
|
const interactionWithHelpers = createMessageContextMenuInteraction(commandInteraction, {
|
|
1300
1304
|
onAck: (response) => ackResolver?.(response),
|
|
1301
1305
|
sendFollowUp,
|
|
1306
|
+
canRespond: (id) => this.canRespond(id),
|
|
1307
|
+
trackResponse: (id, token, state) => this.trackInteractionState(id, token, state),
|
|
1302
1308
|
});
|
|
1303
1309
|
response = await command.handler(interactionWithHelpers);
|
|
1304
1310
|
resolvedResponse =
|
|
@@ -146,7 +146,7 @@ export interface CommandInteraction extends Omit<APIChatInputApplicationCommandI
|
|
|
146
146
|
reply(data: InteractionMessageData): APIInteractionResponseChannelMessageWithSource;
|
|
147
147
|
followUp(data: InteractionMessageData): Promise<APIInteractionResponseChannelMessageWithSource>;
|
|
148
148
|
edit(data?: InteractionMessageData): APIInteractionResponseUpdateMessage;
|
|
149
|
-
editReply(data?: InteractionMessageData): Promise<APIInteractionResponseUpdateMessage>;
|
|
149
|
+
editReply(data?: InteractionMessageData): Promise<APIInteractionResponseChannelMessageWithSource | APIInteractionResponseUpdateMessage>;
|
|
150
150
|
deferReply(options?: DeferReplyOptions): APIInteractionResponseDeferredChannelMessageWithSource;
|
|
151
151
|
showModal(data: APIModalInteractionResponseCallbackData | {
|
|
152
152
|
toJSON(): APIModalInteractionResponseCallbackData;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApplicationCommandOptionType, InteractionResponseType, } from "discord-api-types/v10";
|
|
1
|
+
import { ApplicationCommandOptionType, InteractionResponseType, InteractionType, } from "discord-api-types/v10";
|
|
2
2
|
import { normaliseInteractionMessageData, normaliseMessageFlags, } from "./interactionMessageHelpers.js";
|
|
3
3
|
export const ResolvedUserOption = {};
|
|
4
4
|
export const MentionableOption = {};
|
|
@@ -405,10 +405,24 @@ export function createCommandInteraction(interaction, helpers) {
|
|
|
405
405
|
if (!this.canRespond?.(this.id)) {
|
|
406
406
|
throw new Error('Interaction cannot edit reply: expired');
|
|
407
407
|
}
|
|
408
|
-
|
|
408
|
+
// Slash commands (type 2) MUST use ChannelMessageWithSource (type 4) for their initial response,
|
|
409
|
+
// or UpdateMessage (type 7) if they are updating a component interaction message.
|
|
410
|
+
// However, for as-yet-unresponded slash commands, we need type 4.
|
|
411
|
+
const interactionAny = interaction;
|
|
412
|
+
const isComponent = interactionAny.type === InteractionType.MessageComponent;
|
|
413
|
+
let response;
|
|
414
|
+
if (isComponent) {
|
|
415
|
+
response = createMessageResponse(InteractionResponseType.UpdateMessage, data);
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
response = createMessageResponse(InteractionResponseType.ChannelMessageWithSource, data);
|
|
419
|
+
}
|
|
409
420
|
// If it's already deferred or responded, we MUST use a webhook
|
|
410
421
|
if (this.sendFollowUp && (isDeferred || hasResponded)) {
|
|
411
422
|
await this.sendFollowUp(this.token, response, '@original');
|
|
423
|
+
// If we already sent an ACK (like a DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE),
|
|
424
|
+
// we return the original captured response to avoid sending type 4/7 back to the initial POST.
|
|
425
|
+
return capturedResponse;
|
|
412
426
|
}
|
|
413
427
|
// Track response
|
|
414
428
|
this.trackResponse?.(this.id, this.token, 'responded');
|
|
@@ -14,6 +14,8 @@ export type ContextMenuInteractionHelpers = {
|
|
|
14
14
|
}) => APIModalInteractionResponse;
|
|
15
15
|
onAck?: (response: APIInteractionResponse) => void;
|
|
16
16
|
sendFollowUp?: (token: string, response: APIInteractionResponse, messageId?: string) => Promise<void>;
|
|
17
|
+
canRespond?: (interactionId: string) => boolean;
|
|
18
|
+
trackResponse?: (interactionId: string, token: string, state: 'responded' | 'deferred') => void;
|
|
17
19
|
};
|
|
18
20
|
/**
|
|
19
21
|
* User context menu interaction with helper methods.
|
|
@@ -46,6 +48,8 @@ export declare const AppCommandInteraction: {};
|
|
|
46
48
|
export declare function createUserContextMenuInteraction(interaction: APIUserApplicationCommandInteraction, helpers?: {
|
|
47
49
|
onAck?: (response: APIInteractionResponse) => void;
|
|
48
50
|
sendFollowUp?: (token: string, response: APIInteractionResponse, messageId?: string) => Promise<void>;
|
|
51
|
+
canRespond?: (interactionId: string) => boolean;
|
|
52
|
+
trackResponse?: (interactionId: string, token: string, state: 'responded' | 'deferred') => void;
|
|
49
53
|
}): UserContextMenuInteraction;
|
|
50
54
|
/**
|
|
51
55
|
* Wraps a raw message context menu interaction with helper methods.
|
|
@@ -57,6 +61,8 @@ export declare function createUserContextMenuInteraction(interaction: APIUserApp
|
|
|
57
61
|
export declare function createMessageContextMenuInteraction(interaction: APIMessageApplicationCommandInteraction, helpers?: {
|
|
58
62
|
onAck?: (response: APIInteractionResponse) => void;
|
|
59
63
|
sendFollowUp?: (token: string, response: APIInteractionResponse, messageId?: string) => Promise<void>;
|
|
64
|
+
canRespond?: (interactionId: string) => boolean;
|
|
65
|
+
trackResponse?: (interactionId: string, token: string, state: 'responded' | 'deferred') => void;
|
|
60
66
|
}): MessageContextMenuInteraction;
|
|
61
67
|
/**
|
|
62
68
|
* Wraps a raw primary entry point interaction with helper methods.
|
|
@@ -68,4 +74,6 @@ export declare function createMessageContextMenuInteraction(interaction: APIMess
|
|
|
68
74
|
export declare function createAppCommandInteraction(interaction: APIPrimaryEntryPointCommandInteraction, helpers?: {
|
|
69
75
|
onAck?: (response: APIInteractionResponse) => void;
|
|
70
76
|
sendFollowUp?: (token: string, response: APIInteractionResponse, messageId?: string) => Promise<void>;
|
|
77
|
+
canRespond?: (interactionId: string) => boolean;
|
|
78
|
+
trackResponse?: (interactionId: string, token: string, state: 'responded' | 'deferred') => void;
|
|
71
79
|
}): AppCommandInteraction;
|
|
@@ -28,8 +28,12 @@ function createContextMenuInteractionHelpers(interaction, helpers) {
|
|
|
28
28
|
return captureResponse({ type });
|
|
29
29
|
}
|
|
30
30
|
const reply = (data) => {
|
|
31
|
+
if (helpers?.canRespond && !helpers.canRespond(interaction.id)) {
|
|
32
|
+
throw new Error("[MiniInteraction] Interaction cannot respond: already responded or expired");
|
|
33
|
+
}
|
|
31
34
|
const response = createMessageResponse(InteractionResponseType.ChannelMessageWithSource, data);
|
|
32
35
|
hasResponded = true;
|
|
36
|
+
helpers?.trackResponse?.(interaction.id, interaction.token, 'responded');
|
|
33
37
|
helpers?.onAck?.(response);
|
|
34
38
|
return response;
|
|
35
39
|
};
|
|
@@ -41,20 +45,31 @@ function createContextMenuInteractionHelpers(interaction, helpers) {
|
|
|
41
45
|
return response;
|
|
42
46
|
};
|
|
43
47
|
const editReply = async (data) => {
|
|
44
|
-
|
|
48
|
+
if (helpers?.canRespond && !helpers.canRespond(interaction.id)) {
|
|
49
|
+
throw new Error("[MiniInteraction] Interaction cannot edit reply: expired");
|
|
50
|
+
}
|
|
51
|
+
// Context menu commands (User/Message) MUST use ChannelMessageWithSource (4)
|
|
52
|
+
// for their initial response if it's the first response.
|
|
53
|
+
const response = createMessageResponse(InteractionResponseType.ChannelMessageWithSource, data);
|
|
45
54
|
if (helpers?.sendFollowUp && (isDeferred || hasResponded)) {
|
|
46
55
|
await helpers.sendFollowUp(interaction.token, response, '@original');
|
|
56
|
+
return capturedResponse;
|
|
47
57
|
}
|
|
48
58
|
hasResponded = true;
|
|
59
|
+
helpers?.trackResponse?.(interaction.id, interaction.token, 'responded');
|
|
49
60
|
return response;
|
|
50
61
|
};
|
|
51
62
|
const deferReply = (options = {}) => {
|
|
63
|
+
if (helpers?.canRespond && !helpers.canRespond(interaction.id)) {
|
|
64
|
+
throw new Error("[MiniInteraction] Interaction cannot defer: already responded or expired");
|
|
65
|
+
}
|
|
52
66
|
const flags = normaliseMessageFlags(options.flags);
|
|
53
67
|
const response = captureResponse({
|
|
54
68
|
type: InteractionResponseType.DeferredChannelMessageWithSource,
|
|
55
69
|
data: flags ? { flags } : undefined,
|
|
56
70
|
});
|
|
57
71
|
isDeferred = true;
|
|
72
|
+
helpers?.trackResponse?.(interaction.id, interaction.token, 'deferred');
|
|
58
73
|
helpers?.onAck?.(response);
|
|
59
74
|
return response;
|
|
60
75
|
};
|
|
@@ -70,10 +85,13 @@ function createContextMenuInteractionHelpers(interaction, helpers) {
|
|
|
70
85
|
getResponse,
|
|
71
86
|
reply,
|
|
72
87
|
followUp,
|
|
73
|
-
editReply,
|
|
88
|
+
editReply: editReply,
|
|
74
89
|
deferReply,
|
|
75
90
|
showModal,
|
|
91
|
+
onAck: helpers?.onAck,
|
|
76
92
|
sendFollowUp: helpers?.sendFollowUp,
|
|
93
|
+
canRespond: helpers?.canRespond,
|
|
94
|
+
trackResponse: helpers?.trackResponse,
|
|
77
95
|
};
|
|
78
96
|
}
|
|
79
97
|
/**
|
|
@@ -24,6 +24,9 @@ export function createMessageComponentInteraction(interaction, helpers) {
|
|
|
24
24
|
return response;
|
|
25
25
|
};
|
|
26
26
|
const reply = async (data) => {
|
|
27
|
+
if (helpers?.canRespond && !helpers.canRespond(interaction.id)) {
|
|
28
|
+
throw new Error("[MiniInteraction] Interaction cannot respond: already responded or expired");
|
|
29
|
+
}
|
|
27
30
|
const normalisedData = normaliseInteractionMessageData(data);
|
|
28
31
|
if (!normalisedData) {
|
|
29
32
|
throw new Error("[MiniInteraction] Component replies require response data to be provided.");
|
|
@@ -38,9 +41,13 @@ export function createMessageComponentInteraction(interaction, helpers) {
|
|
|
38
41
|
else {
|
|
39
42
|
helpers?.onAck?.(response);
|
|
40
43
|
}
|
|
44
|
+
helpers?.trackResponse?.(interaction.id, interaction.token, 'responded');
|
|
41
45
|
return response;
|
|
42
46
|
};
|
|
43
47
|
const deferReply = (options) => {
|
|
48
|
+
if (helpers?.canRespond && !helpers.canRespond(interaction.id)) {
|
|
49
|
+
throw new Error("[MiniInteraction] Interaction cannot defer: already responded or expired");
|
|
50
|
+
}
|
|
44
51
|
const flags = normaliseMessageFlags(options?.flags);
|
|
45
52
|
const response = flags !== undefined
|
|
46
53
|
? {
|
|
@@ -52,10 +59,14 @@ export function createMessageComponentInteraction(interaction, helpers) {
|
|
|
52
59
|
};
|
|
53
60
|
captureResponse(response);
|
|
54
61
|
isDeferred = true;
|
|
62
|
+
helpers?.trackResponse?.(interaction.id, interaction.token, 'deferred');
|
|
55
63
|
helpers?.onAck?.(response);
|
|
56
64
|
return response;
|
|
57
65
|
};
|
|
58
66
|
const update = async (data) => {
|
|
67
|
+
if (helpers?.canRespond && !helpers.canRespond(interaction.id)) {
|
|
68
|
+
throw new Error("[MiniInteraction] Interaction cannot update: already responded or expired");
|
|
69
|
+
}
|
|
59
70
|
const normalisedData = normaliseInteractionMessageData(data);
|
|
60
71
|
const response = captureResponse(normalisedData
|
|
61
72
|
? {
|
|
@@ -71,13 +82,18 @@ export function createMessageComponentInteraction(interaction, helpers) {
|
|
|
71
82
|
else {
|
|
72
83
|
helpers?.onAck?.(response);
|
|
73
84
|
}
|
|
85
|
+
helpers?.trackResponse?.(interaction.id, interaction.token, 'responded');
|
|
74
86
|
return response;
|
|
75
87
|
};
|
|
76
88
|
const deferUpdate = () => {
|
|
89
|
+
if (helpers?.canRespond && !helpers.canRespond(interaction.id)) {
|
|
90
|
+
throw new Error("[MiniInteraction] Interaction cannot defer update: already responded or expired");
|
|
91
|
+
}
|
|
77
92
|
const response = captureResponse({
|
|
78
93
|
type: InteractionResponseType.DeferredMessageUpdate,
|
|
79
94
|
});
|
|
80
95
|
isDeferred = true;
|
|
96
|
+
helpers?.trackResponse?.(interaction.id, interaction.token, 'deferred');
|
|
81
97
|
helpers?.onAck?.(response);
|
|
82
98
|
return response;
|
|
83
99
|
};
|
package/package.json
CHANGED