@minesa-org/mini-interaction 0.2.4 → 0.2.5
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.d.ts +5 -0
- package/dist/clients/MiniInteraction.js +36 -0
- package/dist/utils/CommandInteractionOptions.d.ts +2 -0
- package/dist/utils/CommandInteractionOptions.js +9 -7
- package/dist/utils/MessageComponentInteraction.d.ts +7 -0
- package/dist/utils/MessageComponentInteraction.js +20 -4
- package/dist/utils/ModalSubmitInteraction.d.ts +8 -15
- package/dist/utils/ModalSubmitInteraction.js +22 -55
- package/package.json +1 -1
|
@@ -394,5 +394,10 @@ export declare class MiniInteraction {
|
|
|
394
394
|
* Handles execution of an application command interaction.
|
|
395
395
|
*/
|
|
396
396
|
private handleApplicationCommand;
|
|
397
|
+
/**
|
|
398
|
+
* Sends a follow-up response or edits an existing response via Discord's interaction webhooks.
|
|
399
|
+
* This is used for interactions that have already been acknowledged (e.g., via deferReply).
|
|
400
|
+
*/
|
|
401
|
+
private sendFollowUp;
|
|
397
402
|
}
|
|
398
403
|
export {};
|
|
@@ -1125,8 +1125,11 @@ export class MiniInteraction {
|
|
|
1125
1125
|
const ackPromise = new Promise((resolve) => {
|
|
1126
1126
|
ackResolver = resolve;
|
|
1127
1127
|
});
|
|
1128
|
+
// Helper to send follow-up responses via webhooks
|
|
1129
|
+
const sendFollowUp = (token, data) => this.sendFollowUp(token, data);
|
|
1128
1130
|
const interactionWithHelpers = createMessageComponentInteraction(interaction, {
|
|
1129
1131
|
onAck: (response) => ackResolver?.(response),
|
|
1132
|
+
sendFollowUp,
|
|
1130
1133
|
});
|
|
1131
1134
|
// Wrap component handler with timeout and acknowledgment
|
|
1132
1135
|
const timeoutWrapper = createTimeoutWrapper(async () => {
|
|
@@ -1187,8 +1190,11 @@ export class MiniInteraction {
|
|
|
1187
1190
|
const ackPromise = new Promise((resolve) => {
|
|
1188
1191
|
ackResolver = resolve;
|
|
1189
1192
|
});
|
|
1193
|
+
// Helper to send follow-up responses via webhooks
|
|
1194
|
+
const sendFollowUp = (token, data) => this.sendFollowUp(token, data);
|
|
1190
1195
|
const interactionWithHelpers = createModalSubmitInteraction(interaction, {
|
|
1191
1196
|
onAck: (response) => ackResolver?.(response),
|
|
1197
|
+
sendFollowUp,
|
|
1192
1198
|
});
|
|
1193
1199
|
// Wrap modal handler with timeout and acknowledgment
|
|
1194
1200
|
const timeoutWrapper = createTimeoutWrapper(async () => {
|
|
@@ -1252,6 +1258,8 @@ export class MiniInteraction {
|
|
|
1252
1258
|
const ackPromise = new Promise((resolve) => {
|
|
1253
1259
|
ackResolver = resolve;
|
|
1254
1260
|
});
|
|
1261
|
+
// Helper to send follow-up responses via webhooks
|
|
1262
|
+
const sendFollowUp = (token, data) => this.sendFollowUp(token, data);
|
|
1255
1263
|
// Create a timeout wrapper for the command handler
|
|
1256
1264
|
const timeoutWrapper = createTimeoutWrapper(async () => {
|
|
1257
1265
|
// Check if it's a chat input (slash) command
|
|
@@ -1261,6 +1269,7 @@ export class MiniInteraction {
|
|
|
1261
1269
|
canRespond: (id) => this.canRespond(id),
|
|
1262
1270
|
trackResponse: (id, token, state) => this.trackInteractionState(id, token, state),
|
|
1263
1271
|
onAck: (response) => ackResolver?.(response),
|
|
1272
|
+
sendFollowUp,
|
|
1264
1273
|
});
|
|
1265
1274
|
response = await command.handler(interactionWithHelpers);
|
|
1266
1275
|
resolvedResponse =
|
|
@@ -1338,6 +1347,33 @@ export class MiniInteraction {
|
|
|
1338
1347
|
};
|
|
1339
1348
|
}
|
|
1340
1349
|
}
|
|
1350
|
+
/**
|
|
1351
|
+
* Sends a follow-up response or edits an existing response via Discord's interaction webhooks.
|
|
1352
|
+
* This is used for interactions that have already been acknowledged (e.g., via deferReply).
|
|
1353
|
+
*/
|
|
1354
|
+
async sendFollowUp(token, response) {
|
|
1355
|
+
const url = `${DISCORD_BASE_URL}/webhooks/${this.applicationId}/${token}/messages/@original`;
|
|
1356
|
+
// Only send follow-up if there is data to send
|
|
1357
|
+
if (!('data' in response) || !response.data) {
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1360
|
+
try {
|
|
1361
|
+
const fetchResponse = await this.fetchImpl(url, {
|
|
1362
|
+
method: "PATCH",
|
|
1363
|
+
headers: {
|
|
1364
|
+
"Content-Type": "application/json",
|
|
1365
|
+
},
|
|
1366
|
+
body: JSON.stringify(response.data),
|
|
1367
|
+
});
|
|
1368
|
+
if (!fetchResponse.ok) {
|
|
1369
|
+
const errorBody = await fetchResponse.text();
|
|
1370
|
+
console.error(`[MiniInteraction] Failed to send follow-up response: [${fetchResponse.status}] ${errorBody}`);
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
catch (error) {
|
|
1374
|
+
console.error(`[MiniInteraction] Error sending follow-up response: ${error instanceof Error ? error.message : String(error)}`);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1341
1377
|
}
|
|
1342
1378
|
const DEFAULT_DISCORD_OAUTH_TEMPLATES = {
|
|
1343
1379
|
success: ({ user }) => {
|
|
@@ -155,6 +155,7 @@ export interface CommandInteraction extends Omit<APIChatInputApplicationCommandI
|
|
|
155
155
|
canRespond?(interactionId: string): boolean;
|
|
156
156
|
trackResponse?(interactionId: string, token: string, state: 'responded' | 'deferred'): void;
|
|
157
157
|
onAck?(response: APIInteractionResponse): void;
|
|
158
|
+
sendFollowUp?(token: string, response: APIInteractionResponse): void;
|
|
158
159
|
}
|
|
159
160
|
export declare const CommandInteraction: {};
|
|
160
161
|
/**
|
|
@@ -169,4 +170,5 @@ export declare function createCommandInteraction(interaction: APIChatInputApplic
|
|
|
169
170
|
trackResponse?: (interactionId: string, token: string, state: 'responded' | 'deferred') => void;
|
|
170
171
|
logTiming?: (interactionId: string, operation: string, startTime: number, success: boolean) => void;
|
|
171
172
|
onAck?: (response: APIInteractionResponse) => void;
|
|
173
|
+
sendFollowUp?: (token: string, response: APIInteractionResponse) => void;
|
|
172
174
|
}): CommandInteraction;
|
|
@@ -379,17 +379,19 @@ export function createCommandInteraction(interaction, helpers) {
|
|
|
379
379
|
if (!this.canRespond?.(this.id)) {
|
|
380
380
|
throw new Error('Interaction cannot respond: already responded or expired');
|
|
381
381
|
}
|
|
382
|
-
const startTime = Date.now();
|
|
383
382
|
const response = createMessageResponse(InteractionResponseType.ChannelMessageWithSource, data);
|
|
384
383
|
// Track response
|
|
385
384
|
this.trackResponse?.(this.id, this.token, 'responded');
|
|
386
385
|
// Notify acknowledgment
|
|
387
386
|
this.onAck?.(response);
|
|
388
|
-
// Log timing if debug enabled
|
|
389
387
|
return response;
|
|
390
388
|
},
|
|
391
389
|
followUp(data) {
|
|
392
|
-
|
|
390
|
+
const response = createMessageResponse(InteractionResponseType.ChannelMessageWithSource, data);
|
|
391
|
+
if (this.sendFollowUp) {
|
|
392
|
+
this.sendFollowUp(this.token, response);
|
|
393
|
+
}
|
|
394
|
+
return response;
|
|
393
395
|
},
|
|
394
396
|
edit(data) {
|
|
395
397
|
return createMessageResponse(InteractionResponseType.UpdateMessage, data);
|
|
@@ -399,11 +401,13 @@ export function createCommandInteraction(interaction, helpers) {
|
|
|
399
401
|
if (!this.canRespond?.(this.id)) {
|
|
400
402
|
throw new Error('Interaction cannot edit reply: already responded, expired, or not deferred');
|
|
401
403
|
}
|
|
402
|
-
const startTime = Date.now();
|
|
403
404
|
const response = createMessageResponse(InteractionResponseType.UpdateMessage, data);
|
|
405
|
+
// If it's already deferred or responded, we MUST use a webhook
|
|
406
|
+
if (this.sendFollowUp) {
|
|
407
|
+
this.sendFollowUp(this.token, response);
|
|
408
|
+
}
|
|
404
409
|
// Track response
|
|
405
410
|
this.trackResponse?.(this.id, this.token, 'responded');
|
|
406
|
-
// Log timing if debug enabled
|
|
407
411
|
return response;
|
|
408
412
|
},
|
|
409
413
|
deferReply(options) {
|
|
@@ -411,7 +415,6 @@ export function createCommandInteraction(interaction, helpers) {
|
|
|
411
415
|
if (!this.canRespond?.(this.id)) {
|
|
412
416
|
throw new Error('Interaction cannot defer: already responded or expired');
|
|
413
417
|
}
|
|
414
|
-
const startTime = Date.now();
|
|
415
418
|
const response = createDeferredResponse(options?.flags !== undefined
|
|
416
419
|
? { flags: options.flags }
|
|
417
420
|
: undefined);
|
|
@@ -419,7 +422,6 @@ export function createCommandInteraction(interaction, helpers) {
|
|
|
419
422
|
this.trackResponse?.(this.id, this.token, 'deferred');
|
|
420
423
|
// Notify acknowledgment
|
|
421
424
|
this.onAck?.(response);
|
|
422
|
-
// Log timing if debug enabled
|
|
423
425
|
return response;
|
|
424
426
|
},
|
|
425
427
|
showModal(data) {
|
|
@@ -28,6 +28,7 @@ type BaseComponentInteractionHelpers = {
|
|
|
28
28
|
toJSON(): APIModalInteractionResponseCallbackData;
|
|
29
29
|
}) => APIModalInteractionResponse;
|
|
30
30
|
onAck?: (response: APIInteractionResponse) => void;
|
|
31
|
+
sendFollowUp?: (token: string, response: APIInteractionResponse) => void;
|
|
31
32
|
};
|
|
32
33
|
/**
|
|
33
34
|
* Button interaction with helper methods.
|
|
@@ -97,6 +98,11 @@ export type MessageComponentInteraction = APIMessageComponentInteraction & {
|
|
|
97
98
|
showModal: (data: APIModalInteractionResponseCallbackData | {
|
|
98
99
|
toJSON(): APIModalInteractionResponseCallbackData;
|
|
99
100
|
}) => APIModalInteractionResponse;
|
|
101
|
+
/**
|
|
102
|
+
* Finalise the interaction response via a webhook follow-up.
|
|
103
|
+
* This is automatically called by reply() and update() if the interaction is deferred.
|
|
104
|
+
*/
|
|
105
|
+
sendFollowUp?: (token: string, response: APIInteractionResponse) => void;
|
|
100
106
|
/**
|
|
101
107
|
* The selected values from a select menu interaction.
|
|
102
108
|
* This property is only present for select menu interactions.
|
|
@@ -138,5 +144,6 @@ export declare const MessageComponentInteraction: {};
|
|
|
138
144
|
*/
|
|
139
145
|
export declare function createMessageComponentInteraction(interaction: APIMessageComponentInteraction, helpers?: {
|
|
140
146
|
onAck?: (response: APIInteractionResponse) => void;
|
|
147
|
+
sendFollowUp?: (token: string, response: APIInteractionResponse) => void;
|
|
141
148
|
}): MessageComponentInteraction;
|
|
142
149
|
export {};
|
|
@@ -17,6 +17,7 @@ export const MessageComponentInteraction = {};
|
|
|
17
17
|
*/
|
|
18
18
|
export function createMessageComponentInteraction(interaction, helpers) {
|
|
19
19
|
let capturedResponse = null;
|
|
20
|
+
let isDeferred = false;
|
|
20
21
|
const captureResponse = (response) => {
|
|
21
22
|
capturedResponse = response;
|
|
22
23
|
return response;
|
|
@@ -30,7 +31,12 @@ export function createMessageComponentInteraction(interaction, helpers) {
|
|
|
30
31
|
type: InteractionResponseType.ChannelMessageWithSource,
|
|
31
32
|
data: normalisedData,
|
|
32
33
|
});
|
|
33
|
-
helpers?.
|
|
34
|
+
if (isDeferred && helpers?.sendFollowUp) {
|
|
35
|
+
helpers.sendFollowUp(interaction.token, response);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
helpers?.onAck?.(response);
|
|
39
|
+
}
|
|
34
40
|
return response;
|
|
35
41
|
};
|
|
36
42
|
const deferReply = (options) => {
|
|
@@ -44,6 +50,7 @@ export function createMessageComponentInteraction(interaction, helpers) {
|
|
|
44
50
|
type: InteractionResponseType.DeferredChannelMessageWithSource,
|
|
45
51
|
};
|
|
46
52
|
captureResponse(response);
|
|
53
|
+
isDeferred = true;
|
|
47
54
|
helpers?.onAck?.(response);
|
|
48
55
|
return response;
|
|
49
56
|
};
|
|
@@ -57,11 +64,19 @@ export function createMessageComponentInteraction(interaction, helpers) {
|
|
|
57
64
|
: {
|
|
58
65
|
type: InteractionResponseType.UpdateMessage,
|
|
59
66
|
};
|
|
67
|
+
if (isDeferred && helpers?.sendFollowUp) {
|
|
68
|
+
helpers.sendFollowUp(interaction.token, response);
|
|
69
|
+
}
|
|
60
70
|
return captureResponse(response);
|
|
61
71
|
};
|
|
62
|
-
const deferUpdate = () =>
|
|
63
|
-
|
|
64
|
-
|
|
72
|
+
const deferUpdate = () => {
|
|
73
|
+
const response = captureResponse({
|
|
74
|
+
type: InteractionResponseType.DeferredMessageUpdate,
|
|
75
|
+
});
|
|
76
|
+
isDeferred = true;
|
|
77
|
+
helpers?.onAck?.(response);
|
|
78
|
+
return response;
|
|
79
|
+
};
|
|
65
80
|
const showModal = (data) => {
|
|
66
81
|
const resolvedData = typeof data === "object" &&
|
|
67
82
|
"toJSON" in data &&
|
|
@@ -183,5 +198,6 @@ export function createMessageComponentInteraction(interaction, helpers) {
|
|
|
183
198
|
getUsers,
|
|
184
199
|
getMentionables,
|
|
185
200
|
onAck: helpers?.onAck,
|
|
201
|
+
sendFollowUp: helpers?.sendFollowUp,
|
|
186
202
|
});
|
|
187
203
|
}
|
|
@@ -7,32 +7,25 @@ export type ModalSubmitInteraction = APIModalSubmitInteraction & {
|
|
|
7
7
|
getResponse: () => APIInteractionResponse | null;
|
|
8
8
|
reply: (data: InteractionMessageData) => APIInteractionResponseChannelMessageWithSource;
|
|
9
9
|
deferReply: (options?: DeferReplyOptions) => APIInteractionResponseDeferredChannelMessageWithSource;
|
|
10
|
-
onAck?: (response: APIInteractionResponse) => void;
|
|
11
|
-
/**
|
|
12
|
-
* Helper method to get the value of a text input component by custom_id.
|
|
13
|
-
* @param customId - The custom_id of the text input component
|
|
14
|
-
* @returns The value of the text input, or undefined if not found
|
|
15
|
-
*/
|
|
16
|
-
getTextInputValue: (customId: string) => string | undefined;
|
|
17
10
|
/**
|
|
18
|
-
* Helper method to get
|
|
19
|
-
* @returns A map of custom_id to value for all text inputs
|
|
11
|
+
* Helper method to get the value of a text input component by its custom ID.
|
|
20
12
|
*/
|
|
21
|
-
|
|
13
|
+
getTextFieldValue: (customId: string) => string | undefined;
|
|
22
14
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* @returns The selected values of the select menu, or undefined if not found
|
|
15
|
+
* Finalise the interaction response via a webhook follow-up.
|
|
16
|
+
* This is automatically called by reply() if the interaction is deferred.
|
|
26
17
|
*/
|
|
27
|
-
|
|
18
|
+
sendFollowUp?: (token: string, response: APIInteractionResponse) => void;
|
|
28
19
|
};
|
|
29
20
|
export declare const ModalSubmitInteraction: {};
|
|
30
21
|
/**
|
|
31
|
-
* Wraps a raw modal submit interaction with helper methods.
|
|
22
|
+
* Wraps a raw modal submit interaction with helper methods mirroring Discord's expected responses.
|
|
32
23
|
*
|
|
33
24
|
* @param interaction - The raw interaction payload from Discord.
|
|
25
|
+
* @param helpers - Optional callback to capture the final interaction response.
|
|
34
26
|
* @returns A helper-augmented interaction object.
|
|
35
27
|
*/
|
|
36
28
|
export declare function createModalSubmitInteraction(interaction: APIModalSubmitInteraction, helpers?: {
|
|
37
29
|
onAck?: (response: APIInteractionResponse) => void;
|
|
30
|
+
sendFollowUp?: (token: string, response: APIInteractionResponse) => void;
|
|
38
31
|
}): ModalSubmitInteraction;
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { InteractionResponseType, } from "discord-api-types/v10";
|
|
1
|
+
import { ComponentType, InteractionResponseType, } from "discord-api-types/v10";
|
|
2
2
|
import { normaliseInteractionMessageData, normaliseMessageFlags, } from "./interactionMessageHelpers.js";
|
|
3
3
|
export const ModalSubmitInteraction = {};
|
|
4
4
|
/**
|
|
5
|
-
* Wraps a raw modal submit interaction with helper methods.
|
|
5
|
+
* Wraps a raw modal submit interaction with helper methods mirroring Discord's expected responses.
|
|
6
6
|
*
|
|
7
7
|
* @param interaction - The raw interaction payload from Discord.
|
|
8
|
+
* @param helpers - Optional callback to capture the final interaction response.
|
|
8
9
|
* @returns A helper-augmented interaction object.
|
|
9
10
|
*/
|
|
10
11
|
export function createModalSubmitInteraction(interaction, helpers) {
|
|
11
12
|
let capturedResponse = null;
|
|
13
|
+
let isDeferred = false;
|
|
12
14
|
const captureResponse = (response) => {
|
|
13
15
|
capturedResponse = response;
|
|
14
16
|
return response;
|
|
@@ -16,13 +18,18 @@ export function createModalSubmitInteraction(interaction, helpers) {
|
|
|
16
18
|
const reply = (data) => {
|
|
17
19
|
const normalisedData = normaliseInteractionMessageData(data);
|
|
18
20
|
if (!normalisedData) {
|
|
19
|
-
throw new Error("[MiniInteraction] Modal
|
|
21
|
+
throw new Error("[MiniInteraction] Modal replies require response data to be provided.");
|
|
20
22
|
}
|
|
21
23
|
const response = captureResponse({
|
|
22
24
|
type: InteractionResponseType.ChannelMessageWithSource,
|
|
23
25
|
data: normalisedData,
|
|
24
26
|
});
|
|
25
|
-
helpers?.
|
|
27
|
+
if (isDeferred && helpers?.sendFollowUp) {
|
|
28
|
+
helpers.sendFollowUp(interaction.token, response);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
helpers?.onAck?.(response);
|
|
32
|
+
}
|
|
26
33
|
return response;
|
|
27
34
|
};
|
|
28
35
|
const deferReply = (options) => {
|
|
@@ -36,69 +43,29 @@ export function createModalSubmitInteraction(interaction, helpers) {
|
|
|
36
43
|
type: InteractionResponseType.DeferredChannelMessageWithSource,
|
|
37
44
|
};
|
|
38
45
|
captureResponse(response);
|
|
46
|
+
isDeferred = true;
|
|
39
47
|
helpers?.onAck?.(response);
|
|
40
48
|
return response;
|
|
41
49
|
};
|
|
42
50
|
const getResponse = () => capturedResponse;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if ("value" in child && "custom_id" in child) {
|
|
51
|
-
textInputs.set(child.custom_id, child.value);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
// Handle labeled components
|
|
56
|
-
else if ("component" in component) {
|
|
57
|
-
const labeledComponent = component.component;
|
|
58
|
-
if ("value" in labeledComponent && "custom_id" in labeledComponent) {
|
|
59
|
-
textInputs.set(labeledComponent.custom_id, labeledComponent.value);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return textInputs;
|
|
64
|
-
};
|
|
65
|
-
// Helper to extract select menu values from modal components
|
|
66
|
-
const extractSelectMenuValues = () => {
|
|
67
|
-
const selectMenuValues = new Map();
|
|
68
|
-
for (const component of interaction.data.components) {
|
|
69
|
-
// Handle action rows
|
|
70
|
-
if ("components" in component && Array.isArray(component.components)) {
|
|
71
|
-
for (const child of component.components) {
|
|
72
|
-
if ("values" in child && "custom_id" in child && Array.isArray(child.values)) {
|
|
73
|
-
selectMenuValues.set(child.custom_id, child.values);
|
|
51
|
+
const getTextFieldValue = (customId) => {
|
|
52
|
+
for (const actionRow of interaction.data.components) {
|
|
53
|
+
if ("components" in actionRow && Array.isArray(actionRow.components)) {
|
|
54
|
+
for (const component of actionRow.components) {
|
|
55
|
+
if (component.type === ComponentType.TextInput &&
|
|
56
|
+
component.custom_id === customId) {
|
|
57
|
+
return component.value;
|
|
74
58
|
}
|
|
75
59
|
}
|
|
76
60
|
}
|
|
77
|
-
// Handle labeled components (unlikely for select menus but good for completeness if spec allows)
|
|
78
|
-
else if ("component" in component) {
|
|
79
|
-
const labeledComponent = component.component; // Using any as ModalSubmitComponent might not cover select menus fully in types yet or strictness varies
|
|
80
|
-
if ("values" in labeledComponent && "custom_id" in labeledComponent && Array.isArray(labeledComponent.values)) {
|
|
81
|
-
selectMenuValues.set(labeledComponent.custom_id, labeledComponent.values);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
61
|
}
|
|
85
|
-
return
|
|
86
|
-
};
|
|
87
|
-
const textInputValues = extractTextInputs();
|
|
88
|
-
const selectMenuValues = extractSelectMenuValues();
|
|
89
|
-
const getTextInputValue = (customId) => {
|
|
90
|
-
return textInputValues.get(customId);
|
|
91
|
-
};
|
|
92
|
-
const getTextInputValues = () => {
|
|
93
|
-
return new Map(textInputValues);
|
|
62
|
+
return undefined;
|
|
94
63
|
};
|
|
95
64
|
return Object.assign(interaction, {
|
|
96
65
|
reply,
|
|
97
66
|
deferReply,
|
|
98
67
|
getResponse,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
getSelectMenuValues: (customId) => selectMenuValues.get(customId),
|
|
102
|
-
onAck: helpers?.onAck,
|
|
68
|
+
getTextFieldValue,
|
|
69
|
+
sendFollowUp: helpers?.sendFollowUp,
|
|
103
70
|
});
|
|
104
71
|
}
|
package/package.json
CHANGED