@open-discord-bots/framework 0.3.1 → 0.3.3

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/api/main.js CHANGED
@@ -43,7 +43,7 @@ export class ODMain {
43
43
  constructor(managers, project) {
44
44
  this.project = project;
45
45
  this.versions = managers.versions;
46
- this.versions.add(ODVersion.fromString("opendiscord:api", "v0.3.1"));
46
+ this.versions.add(ODVersion.fromString("opendiscord:api", "v0.3.3"));
47
47
  this.versions.add(ODVersion.fromString("opendiscord:livestatus", "v2.0.0"));
48
48
  this.debugfile = managers.debugfile;
49
49
  this.console = managers.console;
@@ -150,6 +150,12 @@ export interface ODSharedFuseList {
150
150
  messageBuildersLoading: boolean;
151
151
  /**Load the default Open Discord modal builders. */
152
152
  modalBuildersLoading: boolean;
153
+ /**Load the default Open Discord shared components. */
154
+ sharedComponentsLoading: boolean;
155
+ /**Load the default Open Discord message components. */
156
+ messageComponentsLoading: boolean;
157
+ /**Load the default Open Discord modal components. */
158
+ modalComponentsLoading: boolean;
153
159
  /**Load the default Open Discord command responders. */
154
160
  commandRespondersLoading: boolean;
155
161
  /**Load the default Open Discord button responders. */
@@ -86,6 +86,9 @@ export class ODSharedFuseManager extends ODFuseManager {
86
86
  embedBuildersLoading: true,
87
87
  messageBuildersLoading: true,
88
88
  modalBuildersLoading: true,
89
+ sharedComponentsLoading: true,
90
+ messageComponentsLoading: true,
91
+ modalComponentsLoading: true,
89
92
  commandRespondersLoading: true,
90
93
  buttonRespondersLoading: true,
91
94
  dropdownRespondersLoading: true,
@@ -171,8 +171,8 @@ export declare class ODCommandResponderInstance extends ODBaseResponderInstance
171
171
  cmd: ODSlashCommand | ODTextCommand;
172
172
  /**The type/source of instance. (from text or slash command) */
173
173
  type: "message" | "interaction";
174
- /**Did a worker already reply to this instance/interaction? */
175
- didReply: boolean;
174
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
175
+ protected ignoreResponderTimeout: boolean;
176
176
  /**The manager for all options of this command. */
177
177
  options: ODCommandResponderInstanceOptions;
178
178
  /**The user who triggered this command. */
@@ -252,8 +252,8 @@ export declare class ODButtonResponderManager<IdList extends ODButtonResponderMa
252
252
  export declare class ODButtonResponderInstance extends ODBaseResponderInstance {
253
253
  /**The interaction which is the source of this instance. */
254
254
  interaction: discord.ButtonInteraction;
255
- /**Did a worker already reply to this instance/interaction? */
256
- didReply: boolean;
255
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
256
+ protected ignoreResponderTimeout: boolean;
257
257
  /**The user who triggered this button. */
258
258
  user: discord.User;
259
259
  /**The guild member who triggered this button. */
@@ -361,8 +361,8 @@ export declare class ODDropdownResponderInstanceValues {
361
361
  export declare class ODDropdownResponderInstance extends ODBaseResponderInstance {
362
362
  /**The interaction which is the source of this instance. */
363
363
  interaction: discord.AnySelectMenuInteraction;
364
- /**Did a worker already reply to this instance/interaction? */
365
- didReply: boolean;
364
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
365
+ protected ignoreResponderTimeout: boolean;
366
366
  /**The dropdown type. */
367
367
  type: ODDropdownData["type"];
368
368
  /**The manager for all values of this dropdown. */
@@ -467,8 +467,8 @@ export declare class ODModalResponderInstanceValues {
467
467
  export declare class ODModalResponderInstance extends ODBaseResponderInstance {
468
468
  /**The interaction which is the source of this instance. */
469
469
  interaction: discord.ModalSubmitInteraction;
470
- /**Did a worker already reply to this instance/interaction? */
471
- didReply: boolean;
470
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
471
+ protected ignoreResponderTimeout: boolean;
472
472
  /**The manager for all fields of this modal. */
473
473
  values: ODModalResponderInstanceValues;
474
474
  /**The user who triggered this modal. */
@@ -543,8 +543,8 @@ export declare class ODContextMenuResponderManager<IdList extends ODContextMenuR
543
543
  export declare class ODContextMenuResponderInstance extends ODBaseResponderInstance {
544
544
  /**The interaction which is the source of this instance. */
545
545
  interaction: discord.ContextMenuCommandInteraction;
546
- /**Did a worker already reply to this instance/interaction? */
547
- didReply: boolean;
546
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
547
+ protected ignoreResponderTimeout: boolean;
548
548
  /**The context menu wich is the source of this instance. */
549
549
  menu: ODContextMenu;
550
550
  /**The user who triggered this context menu. */
@@ -372,8 +372,8 @@ export class ODCommandResponderInstance extends ODBaseResponderInstance {
372
372
  cmd;
373
373
  /**The type/source of instance. (from text or slash command) */
374
374
  type;
375
- /**Did a worker already reply to this instance/interaction? */
376
- didReply = false;
375
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
376
+ ignoreResponderTimeout = false;
377
377
  /**The manager for all options of this command. */
378
378
  options;
379
379
  /**The user who triggered this command. */
@@ -397,27 +397,27 @@ export class ODCommandResponderInstance extends ODBaseResponderInstance {
397
397
  this.guild = interaction.guild;
398
398
  this.channel = interaction.channel;
399
399
  setTimeout(async () => {
400
- if (!this.didReply) {
401
- try {
402
- if (!errorCallback) {
403
- this.reply({ id: new ODId("opendiscord:unknown-error"), ephemeral: true, message: {
404
- content: ":x: **Something went wrong while replying to this command!**"
405
- } });
406
- }
407
- else {
408
- const errorResponse = await errorCallback(this, (this.type == "interaction") ? "slash" : "text");
409
- //auto-delete timeout error message after 5sec when text-based
410
- if (errorResponse.success && this.type == "message")
411
- setTimeout(() => {
412
- if (errorResponse.message?.deletable)
413
- errorResponse.message?.delete();
414
- }, 5000);
415
- }
400
+ if (this.ignoreResponderTimeout)
401
+ return;
402
+ try {
403
+ if (!errorCallback) {
404
+ this.reply({ id: new ODId("opendiscord:unknown-error"), ephemeral: true, message: {
405
+ content: ":x: **Something went wrong while replying to this command!**"
406
+ } });
416
407
  }
417
- catch (err) {
418
- process.emit("uncaughtException", err);
408
+ else {
409
+ const errorResponse = await errorCallback(this, (this.type == "interaction") ? "slash" : "text");
410
+ //auto-delete timeout error message after 5sec when text-based
411
+ if (errorResponse.success && this.type == "message")
412
+ setTimeout(() => {
413
+ if (errorResponse.message?.deletable)
414
+ errorResponse.message?.delete();
415
+ }, 5000);
419
416
  }
420
417
  }
418
+ catch (err) {
419
+ process.emit("uncaughtException", err);
420
+ }
421
421
  }, timeoutMs ?? 2500);
422
422
  }
423
423
  /**Reply to this command. */
@@ -427,18 +427,18 @@ export class ODCommandResponderInstance extends ODBaseResponderInstance {
427
427
  if (this.type == "interaction" && this.interaction instanceof discord.ChatInputCommandInteraction) {
428
428
  if (this.interaction.replied || this.interaction.deferred) {
429
429
  const sent = await this.interaction.editReply(finalMessage);
430
- this.didReply = true;
430
+ this.ignoreResponderTimeout = true;
431
431
  return { success: true, message: sent };
432
432
  }
433
433
  else {
434
434
  const sent = await this.interaction.reply(finalMessage);
435
- this.didReply = true;
435
+ this.ignoreResponderTimeout = true;
436
436
  return { success: true, message: await sent.fetch() };
437
437
  }
438
438
  }
439
439
  else if (this.type == "message" && this.interaction instanceof discord.Message && this.interaction.channel.type != discord.ChannelType.GroupDM) {
440
440
  const sent = await this.interaction.channel.send(finalMessage);
441
- this.didReply = true;
441
+ this.ignoreResponderTimeout = true;
442
442
  return { success: true, message: sent };
443
443
  }
444
444
  else
@@ -450,23 +450,23 @@ export class ODCommandResponderInstance extends ODBaseResponderInstance {
450
450
  }
451
451
  /**Defer this command. */
452
452
  async defer(ephemeral) {
453
+ this.ignoreResponderTimeout = true;
453
454
  if (this.type != "interaction" || !(this.interaction instanceof discord.ChatInputCommandInteraction))
454
455
  return false;
455
456
  if (this.interaction.deferred || this.interaction.replied)
456
457
  return false;
457
458
  const msgFlags = ephemeral ? [discord.MessageFlags.Ephemeral] : [];
458
459
  await this.interaction.deferReply({ flags: msgFlags });
459
- this.didReply = true;
460
460
  return true;
461
461
  }
462
462
  /**Show a modal as reply to this command. */
463
463
  async modal(modal) {
464
+ this.ignoreResponderTimeout = true;
464
465
  if (this.type != "interaction" || !(this.interaction instanceof discord.ChatInputCommandInteraction))
465
466
  return false;
466
467
  if (this.interaction.deferred || this.interaction.replied)
467
468
  return false;
468
469
  await this.interaction.showModal(modal.modal);
469
- this.didReply = true;
470
470
  return true;
471
471
  }
472
472
  }
@@ -553,8 +553,8 @@ export class ODButtonResponderManager extends ODManager {
553
553
  export class ODButtonResponderInstance extends ODBaseResponderInstance {
554
554
  /**The interaction which is the source of this instance. */
555
555
  interaction;
556
- /**Did a worker already reply to this instance/interaction? */
557
- didReply = false;
556
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
557
+ ignoreResponderTimeout = false;
558
558
  /**The user who triggered this button. */
559
559
  user;
560
560
  /**The guild member who triggered this button. */
@@ -576,21 +576,21 @@ export class ODButtonResponderInstance extends ODBaseResponderInstance {
576
576
  this.channel = interaction.channel;
577
577
  this.message = interaction.message;
578
578
  setTimeout(async () => {
579
- if (!this.didReply) {
580
- try {
581
- if (!errorCallback) {
582
- this.reply({ id: new ODId("opendiscord:unknown-error"), ephemeral: true, message: {
583
- content: ":x: **Something went wrong while replying to this button!**"
584
- } });
585
- }
586
- else {
587
- await errorCallback(this, "button");
588
- }
579
+ if (this.ignoreResponderTimeout)
580
+ return;
581
+ try {
582
+ if (!errorCallback) {
583
+ this.reply({ id: new ODId("opendiscord:unknown-error"), ephemeral: true, message: {
584
+ content: ":x: **Something went wrong while replying to this button!**"
585
+ } });
589
586
  }
590
- catch (err) {
591
- process.emit("uncaughtException", err);
587
+ else {
588
+ await errorCallback(this, "button");
592
589
  }
593
590
  }
591
+ catch (err) {
592
+ process.emit("uncaughtException", err);
593
+ }
594
594
  }, timeoutMs ?? 2500);
595
595
  }
596
596
  /**Reply to this button. */
@@ -599,12 +599,12 @@ export class ODButtonResponderInstance extends ODBaseResponderInstance {
599
599
  const finalMessage = this.getMessageFromBuildResult(build, "interaction");
600
600
  if (this.interaction.replied || this.interaction.deferred) {
601
601
  const sent = await this.interaction.editReply(finalMessage);
602
- this.didReply = true;
602
+ this.ignoreResponderTimeout = true;
603
603
  return { success: true, message: sent };
604
604
  }
605
605
  else {
606
606
  const sent = await this.interaction.reply(finalMessage);
607
- this.didReply = true;
607
+ this.ignoreResponderTimeout = true;
608
608
  return { success: true, message: await sent.fetch() };
609
609
  }
610
610
  }
@@ -618,12 +618,12 @@ export class ODButtonResponderInstance extends ODBaseResponderInstance {
618
618
  const finalMessage = this.getMessageFromBuildResult(build, "interaction");
619
619
  if (this.interaction.replied || this.interaction.deferred) {
620
620
  const sent = await this.interaction.editReply(finalMessage);
621
- this.didReply = true;
621
+ this.ignoreResponderTimeout = true;
622
622
  return { success: true, message: await sent.fetch() };
623
623
  }
624
624
  else {
625
625
  const sent = await this.interaction.update(finalMessage);
626
- this.didReply = true;
626
+ this.ignoreResponderTimeout = true;
627
627
  return { success: true, message: await sent.fetch() };
628
628
  }
629
629
  }
@@ -633,6 +633,7 @@ export class ODButtonResponderInstance extends ODBaseResponderInstance {
633
633
  }
634
634
  /**Defer this button. */
635
635
  async defer(type, ephemeral) {
636
+ this.ignoreResponderTimeout = true;
636
637
  if (this.interaction.deferred || this.interaction.replied)
637
638
  return false;
638
639
  if (type == "reply") {
@@ -642,15 +643,14 @@ export class ODButtonResponderInstance extends ODBaseResponderInstance {
642
643
  else {
643
644
  await this.interaction.deferUpdate();
644
645
  }
645
- this.didReply = true;
646
646
  return true;
647
647
  }
648
648
  /**Show a modal as reply to this button. */
649
649
  async modal(modal) {
650
+ this.ignoreResponderTimeout = true;
650
651
  if (this.interaction.deferred || this.interaction.replied)
651
652
  return false;
652
653
  await this.interaction.showModal(modal.modal);
653
- this.didReply = true;
654
654
  return true;
655
655
  }
656
656
  getMessageComponent(type, id) {
@@ -839,8 +839,8 @@ export class ODDropdownResponderInstanceValues {
839
839
  export class ODDropdownResponderInstance extends ODBaseResponderInstance {
840
840
  /**The interaction which is the source of this instance. */
841
841
  interaction;
842
- /**Did a worker already reply to this instance/interaction? */
843
- didReply = false;
842
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
843
+ ignoreResponderTimeout = false;
844
844
  /**The dropdown type. */
845
845
  type;
846
846
  /**The manager for all values of this dropdown. */
@@ -884,21 +884,21 @@ export class ODDropdownResponderInstance extends ODBaseResponderInstance {
884
884
  this.channel = interaction.channel;
885
885
  this.message = interaction.message;
886
886
  setTimeout(async () => {
887
- if (!this.didReply) {
888
- try {
889
- if (!errorCallback) {
890
- this.reply({ id: new ODId("opendiscord:unknown-error"), ephemeral: true, message: {
891
- content: ":x: **Something went wrong while replying to this dropdown!**"
892
- } });
893
- }
894
- else {
895
- await errorCallback(this, "dropdown");
896
- }
887
+ if (this.ignoreResponderTimeout)
888
+ return;
889
+ try {
890
+ if (!errorCallback) {
891
+ this.reply({ id: new ODId("opendiscord:unknown-error"), ephemeral: true, message: {
892
+ content: ":x: **Something went wrong while replying to this dropdown!**"
893
+ } });
897
894
  }
898
- catch (err) {
899
- process.emit("uncaughtException", err);
895
+ else {
896
+ await errorCallback(this, "dropdown");
900
897
  }
901
898
  }
899
+ catch (err) {
900
+ process.emit("uncaughtException", err);
901
+ }
902
902
  }, timeoutMs ?? 2500);
903
903
  }
904
904
  /**Reply to this dropdown. */
@@ -907,12 +907,12 @@ export class ODDropdownResponderInstance extends ODBaseResponderInstance {
907
907
  const finalMessage = this.getMessageFromBuildResult(build, "interaction");
908
908
  if (this.interaction.replied || this.interaction.deferred) {
909
909
  const sent = await this.interaction.editReply(finalMessage);
910
- this.didReply = true;
910
+ this.ignoreResponderTimeout = true;
911
911
  return { success: true, message: sent };
912
912
  }
913
913
  else {
914
914
  const sent = await this.interaction.reply(finalMessage);
915
- this.didReply = true;
915
+ this.ignoreResponderTimeout = true;
916
916
  return { success: true, message: await sent.fetch() };
917
917
  }
918
918
  }
@@ -926,12 +926,12 @@ export class ODDropdownResponderInstance extends ODBaseResponderInstance {
926
926
  const finalMessage = this.getMessageFromBuildResult(build, "interaction");
927
927
  if (this.interaction.replied || this.interaction.deferred) {
928
928
  const sent = await this.interaction.editReply(finalMessage);
929
- this.didReply = true;
929
+ this.ignoreResponderTimeout = true;
930
930
  return { success: true, message: await sent.fetch() };
931
931
  }
932
932
  else {
933
933
  const sent = await this.interaction.update(finalMessage);
934
- this.didReply = true;
934
+ this.ignoreResponderTimeout = true;
935
935
  return { success: true, message: await sent.fetch() };
936
936
  }
937
937
  }
@@ -941,6 +941,7 @@ export class ODDropdownResponderInstance extends ODBaseResponderInstance {
941
941
  }
942
942
  /**Defer this dropdown. */
943
943
  async defer(type, ephemeral) {
944
+ this.ignoreResponderTimeout = true;
944
945
  if (this.interaction.deferred || this.interaction.replied)
945
946
  return false;
946
947
  if (type == "reply") {
@@ -950,15 +951,14 @@ export class ODDropdownResponderInstance extends ODBaseResponderInstance {
950
951
  else {
951
952
  await this.interaction.deferUpdate();
952
953
  }
953
- this.didReply = true;
954
954
  return true;
955
955
  }
956
956
  /**Show a modal as reply to this dropdown. */
957
957
  async modal(modal) {
958
+ this.ignoreResponderTimeout = true;
958
959
  if (this.interaction.deferred || this.interaction.replied)
959
960
  return false;
960
961
  await this.interaction.showModal(modal.modal);
961
- this.didReply = true;
962
962
  return true;
963
963
  }
964
964
  getMessageComponent(type, id) {
@@ -1088,8 +1088,8 @@ export class ODModalResponderInstanceValues {
1088
1088
  export class ODModalResponderInstance extends ODBaseResponderInstance {
1089
1089
  /**The interaction which is the source of this instance. */
1090
1090
  interaction;
1091
- /**Did a worker already reply to this instance/interaction? */
1092
- didReply = false;
1091
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
1092
+ ignoreResponderTimeout = false;
1093
1093
  /**The manager for all fields of this modal. */
1094
1094
  values;
1095
1095
  /**The user who triggered this modal. */
@@ -1109,21 +1109,21 @@ export class ODModalResponderInstance extends ODBaseResponderInstance {
1109
1109
  this.guild = interaction.guild;
1110
1110
  this.channel = interaction.channel;
1111
1111
  setTimeout(async () => {
1112
- if (!this.didReply) {
1113
- try {
1114
- if (!errorCallback) {
1115
- this.reply({ id: new ODId("opendiscord:unknown-error"), ephemeral: true, message: {
1116
- content: ":x: **Something went wrong while replying to this modal!**"
1117
- } });
1118
- }
1119
- else {
1120
- await errorCallback(this, "modal");
1121
- }
1112
+ if (this.ignoreResponderTimeout)
1113
+ return;
1114
+ try {
1115
+ if (!errorCallback) {
1116
+ this.reply({ id: new ODId("opendiscord:unknown-error"), ephemeral: true, message: {
1117
+ content: ":x: **Something went wrong while replying to this modal!**"
1118
+ } });
1122
1119
  }
1123
- catch (err) {
1124
- process.emit("uncaughtException", err);
1120
+ else {
1121
+ await errorCallback(this, "modal");
1125
1122
  }
1126
1123
  }
1124
+ catch (err) {
1125
+ process.emit("uncaughtException", err);
1126
+ }
1127
1127
  }, timeoutMs ?? 2500);
1128
1128
  }
1129
1129
  /**Reply to this modal. */
@@ -1131,7 +1131,7 @@ export class ODModalResponderInstance extends ODBaseResponderInstance {
1131
1131
  try {
1132
1132
  const finalMessage = this.getMessageFromBuildResult(build, "interaction");
1133
1133
  const sent = await this.interaction.followUp(finalMessage);
1134
- this.didReply = true;
1134
+ this.ignoreResponderTimeout = true;
1135
1135
  return { success: true, message: sent };
1136
1136
  }
1137
1137
  catch {
@@ -1144,12 +1144,12 @@ export class ODModalResponderInstance extends ODBaseResponderInstance {
1144
1144
  const finalMessage = this.getMessageFromBuildResult(build, "interaction");
1145
1145
  if (this.interaction.replied || this.interaction.deferred) {
1146
1146
  const sent = await this.interaction.editReply(finalMessage);
1147
- this.didReply = true;
1147
+ this.ignoreResponderTimeout = true;
1148
1148
  return { success: true, message: await sent.fetch() };
1149
1149
  }
1150
1150
  else {
1151
1151
  const sent = await this.interaction.reply(finalMessage);
1152
- this.didReply = true;
1152
+ this.ignoreResponderTimeout = true;
1153
1153
  return { success: true, message: await sent.fetch() };
1154
1154
  }
1155
1155
  }
@@ -1159,6 +1159,7 @@ export class ODModalResponderInstance extends ODBaseResponderInstance {
1159
1159
  }
1160
1160
  /**Defer this modal. */
1161
1161
  async defer(type, ephemeral) {
1162
+ this.ignoreResponderTimeout = true;
1162
1163
  if (this.interaction.deferred || this.interaction.replied)
1163
1164
  return false;
1164
1165
  if (type == "reply") {
@@ -1168,7 +1169,6 @@ export class ODModalResponderInstance extends ODBaseResponderInstance {
1168
1169
  else {
1169
1170
  await this.interaction.deferUpdate();
1170
1171
  }
1171
- this.didReply = true;
1172
1172
  return true;
1173
1173
  }
1174
1174
  }
@@ -1241,8 +1241,8 @@ export class ODContextMenuResponderManager extends ODManager {
1241
1241
  export class ODContextMenuResponderInstance extends ODBaseResponderInstance {
1242
1242
  /**The interaction which is the source of this instance. */
1243
1243
  interaction;
1244
- /**Did a worker already reply to this instance/interaction? */
1245
- didReply = false;
1244
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
1245
+ ignoreResponderTimeout = false;
1246
1246
  /**The context menu wich is the source of this instance. */
1247
1247
  menu;
1248
1248
  /**The user who triggered this context menu. */
@@ -1272,21 +1272,21 @@ export class ODContextMenuResponderInstance extends ODBaseResponderInstance {
1272
1272
  else
1273
1273
  throw new ODSystemError("ODContextMenuResponderInstance: Invalid context menu type. Should be of the type User/Message!");
1274
1274
  setTimeout(async () => {
1275
- if (!this.didReply) {
1276
- try {
1277
- if (!errorCallback) {
1278
- this.reply({ id: new ODId("opendiscord:unknown-error"), ephemeral: true, message: {
1279
- content: ":x: **Something went wrong while replying to this context menu!**"
1280
- } });
1281
- }
1282
- else {
1283
- await errorCallback(this, "context-menu");
1284
- }
1275
+ if (this.ignoreResponderTimeout)
1276
+ return;
1277
+ try {
1278
+ if (!errorCallback) {
1279
+ this.reply({ id: new ODId("opendiscord:unknown-error"), ephemeral: true, message: {
1280
+ content: ":x: **Something went wrong while replying to this context menu!**"
1281
+ } });
1285
1282
  }
1286
- catch (err) {
1287
- process.emit("uncaughtException", err);
1283
+ else {
1284
+ await errorCallback(this, "context-menu");
1288
1285
  }
1289
1286
  }
1287
+ catch (err) {
1288
+ process.emit("uncaughtException", err);
1289
+ }
1290
1290
  }, timeoutMs ?? 2500);
1291
1291
  }
1292
1292
  /**Reply to this context menu. */
@@ -1295,12 +1295,12 @@ export class ODContextMenuResponderInstance extends ODBaseResponderInstance {
1295
1295
  const finalMessage = this.getMessageFromBuildResult(build, "interaction");
1296
1296
  if (this.interaction.replied || this.interaction.deferred) {
1297
1297
  const sent = await this.interaction.editReply(finalMessage);
1298
- this.didReply = true;
1298
+ this.ignoreResponderTimeout = true;
1299
1299
  return { success: true, message: sent };
1300
1300
  }
1301
1301
  else {
1302
1302
  const sent = await this.interaction.reply(finalMessage);
1303
- this.didReply = true;
1303
+ this.ignoreResponderTimeout = true;
1304
1304
  return { success: true, message: await sent.fetch() };
1305
1305
  }
1306
1306
  }
@@ -1314,7 +1314,7 @@ export class ODContextMenuResponderInstance extends ODBaseResponderInstance {
1314
1314
  const finalMessage = this.getMessageFromBuildResult(build, "interaction");
1315
1315
  if (this.interaction.replied || this.interaction.deferred) {
1316
1316
  const sent = await this.interaction.editReply(finalMessage);
1317
- this.didReply = true;
1317
+ this.ignoreResponderTimeout = true;
1318
1318
  return { success: true, message: await sent.fetch() };
1319
1319
  }
1320
1320
  else
@@ -1326,21 +1326,21 @@ export class ODContextMenuResponderInstance extends ODBaseResponderInstance {
1326
1326
  }
1327
1327
  /**Defer this context menu. */
1328
1328
  async defer(type, ephemeral) {
1329
+ this.ignoreResponderTimeout = true;
1329
1330
  if (this.interaction.deferred || this.interaction.replied)
1330
1331
  return false;
1331
1332
  if (type == "reply") {
1332
1333
  const msgFlags = ephemeral ? [discord.MessageFlags.Ephemeral] : [];
1333
1334
  await this.interaction.deferReply({ flags: msgFlags });
1334
1335
  }
1335
- this.didReply = true;
1336
1336
  return true;
1337
1337
  }
1338
1338
  /**Show a modal as reply to this context menu. */
1339
1339
  async modal(modal) {
1340
+ this.ignoreResponderTimeout = true;
1340
1341
  if (this.interaction.deferred || this.interaction.replied)
1341
1342
  return false;
1342
1343
  await this.interaction.showModal(modal.modal);
1343
- this.didReply = true;
1344
1344
  return true;
1345
1345
  }
1346
1346
  }
@@ -1,4 +1,5 @@
1
1
  import * as api from "../api/index.js";
2
+ import * as discord from "discord.js";
2
3
  /**## sharedFuses `utility variable`
3
4
  * All shared fuses from Open Discord. Please use `opendiscord.sharedFuses` instead!
4
5
  */
@@ -55,6 +56,12 @@ export declare function ordinalNumber(num: number): string;
55
56
  * Trim/remove all emoji's from a Javascript string.
56
57
  */
57
58
  export declare function trimEmojis(text: string): string;
59
+ /**## getMessageFromBuildResult `utility function`
60
+ * Get the final `messageCreateOptions` from a returned build result from builders/components.
61
+ */
62
+ export declare function getMessageFromBuildResult(build: api.ODMessageBuildResult | api.ODMessageComponentBuildResult, type: "interaction" | "message"): discord.MessageCreateOptions & {
63
+ flags: number[];
64
+ };
58
65
  /**## easterEggs `utility object`
59
66
  * Object containing data for Open Ticket easter eggs.
60
67
  */
@@ -1,6 +1,7 @@
1
1
  import * as fs from "fs";
2
2
  import ansis from "ansis";
3
3
  import * as api from "../api/index.js";
4
+ import * as discord from "discord.js";
4
5
  /**## sharedFuses `utility variable`
5
6
  * All shared fuses from Open Discord. Please use `opendiscord.sharedFuses` instead!
6
7
  */
@@ -163,6 +164,32 @@ export function ordinalNumber(num) {
163
164
  export function trimEmojis(text) {
164
165
  return text.replace(/(\p{Extended_Pictographic}(?:\uFE0F|\uFE0E)?(?:\u200D\p{Extended_Pictographic}(?:\uFE0F|\uFE0E)?)*)/gu, "");
165
166
  }
167
+ /**## getMessageFromBuildResult `utility function`
168
+ * Get the final `messageCreateOptions` from a returned build result from builders/components.
169
+ */
170
+ export function getMessageFromBuildResult(build, type) {
171
+ const msgFlags = [];
172
+ let msgData;
173
+ if ('message' in build) {
174
+ //USING BUILDERS (deprecated)
175
+ msgData = build.message;
176
+ if (build.ephemeral)
177
+ msgFlags.push(discord.MessageFlags.Ephemeral);
178
+ }
179
+ else {
180
+ //USING COMPONENTS
181
+ msgData = build.msg;
182
+ if (type == "interaction" && build.ephemeral)
183
+ msgFlags.push(discord.MessageFlags.Ephemeral); //disabled with regular messages
184
+ if (build.componentsV2)
185
+ msgFlags.push(discord.MessageFlags.IsComponentsV2);
186
+ if (build.supressEmbeds)
187
+ msgFlags.push(discord.MessageFlags.SuppressEmbeds);
188
+ if (build.supressNotifications)
189
+ msgFlags.push(discord.MessageFlags.SuppressNotifications);
190
+ }
191
+ return Object.assign(msgData, { flags: msgFlags });
192
+ }
166
193
  /**## easterEggs `utility object`
167
194
  * Object containing data for Open Ticket easter eggs.
168
195
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@open-discord-bots/framework",
3
3
  "author": "DJj123dj",
4
- "version": "0.3.1",
4
+ "version": "0.3.3",
5
5
  "description": "The core framework of the popular open-source discord bots: Open Ticket & Open Moderation.",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
package/src/api/main.ts CHANGED
@@ -150,7 +150,7 @@ export abstract class ODMain implements ODMainManagers {
150
150
  constructor(managers:ODMainManagers,project:ODProjectType){
151
151
  this.project = project
152
152
  this.versions = managers.versions
153
- this.versions.add(ODVersion.fromString("opendiscord:api","v0.3.1"))
153
+ this.versions.add(ODVersion.fromString("opendiscord:api","v0.3.3"))
154
154
  this.versions.add(ODVersion.fromString("opendiscord:livestatus","v2.0.0"))
155
155
 
156
156
  this.debugfile = managers.debugfile
@@ -177,6 +177,13 @@ export interface ODSharedFuseList {
177
177
  /**Load the default Open Discord modal builders. */
178
178
  modalBuildersLoading:boolean,
179
179
 
180
+ /**Load the default Open Discord shared components. */
181
+ sharedComponentsLoading:boolean,
182
+ /**Load the default Open Discord message components. */
183
+ messageComponentsLoading:boolean,
184
+ /**Load the default Open Discord modal components. */
185
+ modalComponentsLoading:boolean,
186
+
180
187
  /**Load the default Open Discord command responders. */
181
188
  commandRespondersLoading:boolean,
182
189
  /**Load the default Open Discord button responders. */
@@ -310,6 +317,10 @@ export class ODSharedFuseManager extends ODFuseManager<ODSharedFuseList> {
310
317
  messageBuildersLoading:true,
311
318
  modalBuildersLoading:true,
312
319
 
320
+ sharedComponentsLoading:true,
321
+ messageComponentsLoading:true,
322
+ modalComponentsLoading:true,
323
+
313
324
  commandRespondersLoading:true,
314
325
  buttonRespondersLoading:true,
315
326
  dropdownRespondersLoading:true,
@@ -419,8 +419,8 @@ export class ODCommandResponderInstance extends ODBaseResponderInstance {
419
419
  cmd:ODSlashCommand|ODTextCommand
420
420
  /**The type/source of instance. (from text or slash command) */
421
421
  type: "message"|"interaction"
422
- /**Did a worker already reply to this instance/interaction? */
423
- didReply: boolean = false
422
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
423
+ protected ignoreResponderTimeout: boolean = false
424
424
  /**The manager for all options of this command. */
425
425
  options: ODCommandResponderInstanceOptions
426
426
  /**The user who triggered this command. */
@@ -446,24 +446,23 @@ export class ODCommandResponderInstance extends ODBaseResponderInstance {
446
446
 
447
447
 
448
448
  setTimeout(async () => {
449
- if (!this.didReply){
450
- try {
451
- if (!errorCallback){
452
- this.reply({id:new ODId("opendiscord:unknown-error"), ephemeral:true, message:{
453
- content:":x: **Something went wrong while replying to this command!**"
454
- }})
455
- }else{
456
- const errorResponse = await errorCallback(this,(this.type == "interaction") ? "slash" : "text")
457
-
458
- //auto-delete timeout error message after 5sec when text-based
459
- if (errorResponse.success && this.type == "message") setTimeout(() => {
460
- if (errorResponse.message?.deletable) errorResponse.message?.delete()
461
- },5000)
462
- }
449
+ if (this.ignoreResponderTimeout) return
450
+ try {
451
+ if (!errorCallback){
452
+ this.reply({id:new ODId("opendiscord:unknown-error"), ephemeral:true, message:{
453
+ content:":x: **Something went wrong while replying to this command!**"
454
+ }})
455
+ }else{
456
+ const errorResponse = await errorCallback(this,(this.type == "interaction") ? "slash" : "text")
463
457
 
464
- }catch(err){
465
- process.emit("uncaughtException",err)
458
+ //auto-delete timeout error message after 5sec when text-based
459
+ if (errorResponse.success && this.type == "message") setTimeout(() => {
460
+ if (errorResponse.message?.deletable) errorResponse.message?.delete()
461
+ },5000)
466
462
  }
463
+
464
+ }catch(err){
465
+ process.emit("uncaughtException",err)
467
466
  }
468
467
  },timeoutMs ?? 2500)
469
468
  }
@@ -475,16 +474,16 @@ export class ODCommandResponderInstance extends ODBaseResponderInstance {
475
474
  if (this.type == "interaction" && this.interaction instanceof discord.ChatInputCommandInteraction){
476
475
  if (this.interaction.replied || this.interaction.deferred){
477
476
  const sent = await this.interaction.editReply(finalMessage)
478
- this.didReply = true
477
+ this.ignoreResponderTimeout = true
479
478
  return {success:true,message:sent}
480
479
  }else{
481
480
  const sent = await this.interaction.reply(finalMessage)
482
- this.didReply = true
481
+ this.ignoreResponderTimeout = true
483
482
  return {success:true,message:await sent.fetch()}
484
483
  }
485
484
  }else if (this.type == "message" && this.interaction instanceof discord.Message && this.interaction.channel.type != discord.ChannelType.GroupDM){
486
485
  const sent = await this.interaction.channel.send(finalMessage)
487
- this.didReply = true
486
+ this.ignoreResponderTimeout = true
488
487
  return {success:true,message:sent}
489
488
  }else return {success:false,message:null}
490
489
  }catch{
@@ -493,19 +492,19 @@ export class ODCommandResponderInstance extends ODBaseResponderInstance {
493
492
  }
494
493
  /**Defer this command. */
495
494
  async defer(ephemeral:boolean){
495
+ this.ignoreResponderTimeout = true
496
496
  if (this.type != "interaction" || !(this.interaction instanceof discord.ChatInputCommandInteraction)) return false
497
497
  if (this.interaction.deferred || this.interaction.replied) return false
498
498
  const msgFlags: number[] = ephemeral ? [discord.MessageFlags.Ephemeral] : []
499
499
  await this.interaction.deferReply({flags:msgFlags})
500
- this.didReply = true
501
500
  return true
502
501
  }
503
502
  /**Show a modal as reply to this command. */
504
503
  async modal(modal:ODModalBuildResult){
504
+ this.ignoreResponderTimeout = true
505
505
  if (this.type != "interaction" || !(this.interaction instanceof discord.ChatInputCommandInteraction)) return false
506
506
  if (this.interaction.deferred || this.interaction.replied) return false
507
507
  await this.interaction.showModal(modal.modal)
508
- this.didReply = true
509
508
  return true
510
509
  }
511
510
  }
@@ -617,8 +616,8 @@ export class ODButtonResponderManager<IdList extends ODButtonResponderManagerIdC
617
616
  export class ODButtonResponderInstance extends ODBaseResponderInstance {
618
617
  /**The interaction which is the source of this instance. */
619
618
  interaction: discord.ButtonInteraction
620
- /**Did a worker already reply to this instance/interaction? */
621
- didReply: boolean = false
619
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
620
+ protected ignoreResponderTimeout: boolean = false
622
621
  /**The user who triggered this button. */
623
622
  user: discord.User
624
623
  /**The guild member who triggered this button. */
@@ -641,19 +640,18 @@ export class ODButtonResponderInstance extends ODBaseResponderInstance {
641
640
  this.message = interaction.message
642
641
 
643
642
  setTimeout(async () => {
644
- if (!this.didReply){
645
- try {
646
- if (!errorCallback){
647
- this.reply({id:new ODId("opendiscord:unknown-error"), ephemeral:true, message:{
648
- content:":x: **Something went wrong while replying to this button!**"
649
- }})
650
- }else{
651
- await errorCallback(this,"button")
652
- }
653
-
654
- }catch(err){
655
- process.emit("uncaughtException",err)
643
+ if (this.ignoreResponderTimeout) return
644
+ try {
645
+ if (!errorCallback){
646
+ this.reply({id:new ODId("opendiscord:unknown-error"), ephemeral:true, message:{
647
+ content:":x: **Something went wrong while replying to this button!**"
648
+ }})
649
+ }else{
650
+ await errorCallback(this,"button")
656
651
  }
652
+
653
+ }catch(err){
654
+ process.emit("uncaughtException",err)
657
655
  }
658
656
  },timeoutMs ?? 2500)
659
657
  }
@@ -664,11 +662,11 @@ export class ODButtonResponderInstance extends ODBaseResponderInstance {
664
662
  const finalMessage = this.getMessageFromBuildResult(build,"interaction")
665
663
  if (this.interaction.replied || this.interaction.deferred){
666
664
  const sent = await this.interaction.editReply(finalMessage)
667
- this.didReply = true
665
+ this.ignoreResponderTimeout = true
668
666
  return {success:true,message:sent}
669
667
  }else{
670
668
  const sent = await this.interaction.reply(finalMessage)
671
- this.didReply = true
669
+ this.ignoreResponderTimeout = true
672
670
  return {success:true,message:await sent.fetch()}
673
671
  }
674
672
  }catch{
@@ -681,11 +679,11 @@ export class ODButtonResponderInstance extends ODBaseResponderInstance {
681
679
  const finalMessage = this.getMessageFromBuildResult(build,"interaction")
682
680
  if (this.interaction.replied || this.interaction.deferred){
683
681
  const sent = await this.interaction.editReply(finalMessage)
684
- this.didReply = true
682
+ this.ignoreResponderTimeout = true
685
683
  return {success:true,message:await sent.fetch()}
686
684
  }else{
687
685
  const sent = await this.interaction.update(finalMessage)
688
- this.didReply = true
686
+ this.ignoreResponderTimeout = true
689
687
  return {success:true,message:await sent.fetch()}
690
688
  }
691
689
  }catch{
@@ -694,6 +692,7 @@ export class ODButtonResponderInstance extends ODBaseResponderInstance {
694
692
  }
695
693
  /**Defer this button. */
696
694
  async defer(type:"reply"|"update", ephemeral:boolean){
695
+ this.ignoreResponderTimeout = true
697
696
  if (this.interaction.deferred || this.interaction.replied) return false
698
697
  if (type == "reply"){
699
698
  const msgFlags: number[] = ephemeral ? [discord.MessageFlags.Ephemeral] : []
@@ -701,14 +700,13 @@ export class ODButtonResponderInstance extends ODBaseResponderInstance {
701
700
  }else{
702
701
  await this.interaction.deferUpdate()
703
702
  }
704
- this.didReply = true
705
703
  return true
706
704
  }
707
705
  /**Show a modal as reply to this button. */
708
706
  async modal(modal:ODModalBuildResult){
707
+ this.ignoreResponderTimeout = true
709
708
  if (this.interaction.deferred || this.interaction.replied) return false
710
709
  await this.interaction.showModal(modal.modal)
711
- this.didReply = true
712
710
  return true
713
711
  }
714
712
 
@@ -916,8 +914,8 @@ export class ODDropdownResponderInstanceValues {
916
914
  export class ODDropdownResponderInstance extends ODBaseResponderInstance {
917
915
  /**The interaction which is the source of this instance. */
918
916
  interaction: discord.AnySelectMenuInteraction
919
- /**Did a worker already reply to this instance/interaction? */
920
- didReply: boolean = false
917
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
918
+ protected ignoreResponderTimeout: boolean = false
921
919
  /**The dropdown type. */
922
920
  type: ODDropdownData["type"]
923
921
  /**The manager for all values of this dropdown. */
@@ -957,19 +955,18 @@ export class ODDropdownResponderInstance extends ODBaseResponderInstance {
957
955
  this.message = interaction.message
958
956
 
959
957
  setTimeout(async () => {
960
- if (!this.didReply){
961
- try {
962
- if (!errorCallback){
963
- this.reply({id:new ODId("opendiscord:unknown-error"), ephemeral:true, message:{
964
- content:":x: **Something went wrong while replying to this dropdown!**"
965
- }})
966
- }else{
967
- await errorCallback(this,"dropdown")
968
- }
969
-
970
- }catch(err){
971
- process.emit("uncaughtException",err)
958
+ if (this.ignoreResponderTimeout) return
959
+ try {
960
+ if (!errorCallback){
961
+ this.reply({id:new ODId("opendiscord:unknown-error"), ephemeral:true, message:{
962
+ content:":x: **Something went wrong while replying to this dropdown!**"
963
+ }})
964
+ }else{
965
+ await errorCallback(this,"dropdown")
972
966
  }
967
+
968
+ }catch(err){
969
+ process.emit("uncaughtException",err)
973
970
  }
974
971
  },timeoutMs ?? 2500)
975
972
  }
@@ -980,11 +977,11 @@ export class ODDropdownResponderInstance extends ODBaseResponderInstance {
980
977
  const finalMessage = this.getMessageFromBuildResult(build,"interaction")
981
978
  if (this.interaction.replied || this.interaction.deferred){
982
979
  const sent = await this.interaction.editReply(finalMessage)
983
- this.didReply = true
980
+ this.ignoreResponderTimeout = true
984
981
  return {success:true,message:sent}
985
982
  }else{
986
983
  const sent = await this.interaction.reply(finalMessage)
987
- this.didReply = true
984
+ this.ignoreResponderTimeout = true
988
985
  return {success:true,message:await sent.fetch()}
989
986
  }
990
987
  }catch{
@@ -997,11 +994,11 @@ export class ODDropdownResponderInstance extends ODBaseResponderInstance {
997
994
  const finalMessage = this.getMessageFromBuildResult(build,"interaction")
998
995
  if (this.interaction.replied || this.interaction.deferred){
999
996
  const sent = await this.interaction.editReply(finalMessage)
1000
- this.didReply = true
997
+ this.ignoreResponderTimeout = true
1001
998
  return {success:true,message:await sent.fetch()}
1002
999
  }else{
1003
1000
  const sent = await this.interaction.update(finalMessage)
1004
- this.didReply = true
1001
+ this.ignoreResponderTimeout = true
1005
1002
  return {success:true,message:await sent.fetch()}
1006
1003
  }
1007
1004
  }catch{
@@ -1010,6 +1007,7 @@ export class ODDropdownResponderInstance extends ODBaseResponderInstance {
1010
1007
  }
1011
1008
  /**Defer this dropdown. */
1012
1009
  async defer(type:"reply"|"update", ephemeral:boolean){
1010
+ this.ignoreResponderTimeout = true
1013
1011
  if (this.interaction.deferred || this.interaction.replied) return false
1014
1012
  if (type == "reply"){
1015
1013
  const msgFlags: number[] = ephemeral ? [discord.MessageFlags.Ephemeral] : []
@@ -1017,14 +1015,13 @@ export class ODDropdownResponderInstance extends ODBaseResponderInstance {
1017
1015
  }else{
1018
1016
  await this.interaction.deferUpdate()
1019
1017
  }
1020
- this.didReply = true
1021
1018
  return true
1022
1019
  }
1023
1020
  /**Show a modal as reply to this dropdown. */
1024
1021
  async modal(modal:ODModalBuildResult){
1022
+ this.ignoreResponderTimeout = true
1025
1023
  if (this.interaction.deferred || this.interaction.replied) return false
1026
1024
  await this.interaction.showModal(modal.modal)
1027
- this.didReply = true
1028
1025
  return true
1029
1026
  }
1030
1027
 
@@ -1185,8 +1182,8 @@ export class ODModalResponderInstanceValues {
1185
1182
  export class ODModalResponderInstance extends ODBaseResponderInstance {
1186
1183
  /**The interaction which is the source of this instance. */
1187
1184
  interaction: discord.ModalSubmitInteraction
1188
- /**Did a worker already reply to this instance/interaction? */
1189
- didReply: boolean = false
1185
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
1186
+ protected ignoreResponderTimeout: boolean = false
1190
1187
  /**The manager for all fields of this modal. */
1191
1188
  values: ODModalResponderInstanceValues
1192
1189
  /**The user who triggered this modal. */
@@ -1208,19 +1205,18 @@ export class ODModalResponderInstance extends ODBaseResponderInstance {
1208
1205
  this.channel = interaction.channel
1209
1206
 
1210
1207
  setTimeout(async () => {
1211
- if (!this.didReply){
1212
- try {
1213
- if (!errorCallback){
1214
- this.reply({id:new ODId("opendiscord:unknown-error"), ephemeral:true, message:{
1215
- content:":x: **Something went wrong while replying to this modal!**"
1216
- }})
1217
- }else{
1218
- await errorCallback(this,"modal")
1219
- }
1220
-
1221
- }catch(err){
1222
- process.emit("uncaughtException",err)
1208
+ if (this.ignoreResponderTimeout) return
1209
+ try {
1210
+ if (!errorCallback){
1211
+ this.reply({id:new ODId("opendiscord:unknown-error"), ephemeral:true, message:{
1212
+ content:":x: **Something went wrong while replying to this modal!**"
1213
+ }})
1214
+ }else{
1215
+ await errorCallback(this,"modal")
1223
1216
  }
1217
+
1218
+ }catch(err){
1219
+ process.emit("uncaughtException",err)
1224
1220
  }
1225
1221
  },timeoutMs ?? 2500)
1226
1222
  }
@@ -1230,7 +1226,7 @@ export class ODModalResponderInstance extends ODBaseResponderInstance {
1230
1226
  try {
1231
1227
  const finalMessage = this.getMessageFromBuildResult(build,"interaction")
1232
1228
  const sent = await this.interaction.followUp(finalMessage)
1233
- this.didReply = true
1229
+ this.ignoreResponderTimeout = true
1234
1230
  return {success:true,message:sent}
1235
1231
  }catch{
1236
1232
  return {success:false,message:null}
@@ -1242,11 +1238,11 @@ export class ODModalResponderInstance extends ODBaseResponderInstance {
1242
1238
  const finalMessage = this.getMessageFromBuildResult(build,"interaction")
1243
1239
  if (this.interaction.replied || this.interaction.deferred){
1244
1240
  const sent = await this.interaction.editReply(finalMessage)
1245
- this.didReply = true
1241
+ this.ignoreResponderTimeout = true
1246
1242
  return {success:true,message:await sent.fetch()}
1247
1243
  }else{
1248
1244
  const sent = await this.interaction.reply(finalMessage)
1249
- this.didReply = true
1245
+ this.ignoreResponderTimeout = true
1250
1246
  return {success:true,message:await sent.fetch()}
1251
1247
  }
1252
1248
  }catch{
@@ -1255,6 +1251,7 @@ export class ODModalResponderInstance extends ODBaseResponderInstance {
1255
1251
  }
1256
1252
  /**Defer this modal. */
1257
1253
  async defer(type:"reply"|"update", ephemeral:boolean){
1254
+ this.ignoreResponderTimeout = true
1258
1255
  if (this.interaction.deferred || this.interaction.replied) return false
1259
1256
  if (type == "reply"){
1260
1257
  const msgFlags: number[] = ephemeral ? [discord.MessageFlags.Ephemeral] : []
@@ -1262,7 +1259,6 @@ export class ODModalResponderInstance extends ODBaseResponderInstance {
1262
1259
  }else{
1263
1260
  await this.interaction.deferUpdate()
1264
1261
  }
1265
- this.didReply = true
1266
1262
  return true
1267
1263
  }
1268
1264
  }
@@ -1359,8 +1355,8 @@ export class ODContextMenuResponderManager<IdList extends ODContextMenuResponder
1359
1355
  export class ODContextMenuResponderInstance extends ODBaseResponderInstance {
1360
1356
  /**The interaction which is the source of this instance. */
1361
1357
  interaction: discord.ContextMenuCommandInteraction
1362
- /**Did a worker already reply to this instance/interaction? */
1363
- didReply: boolean = false
1358
+ /**Switches to `true` when a worker replies, edits or defers interaction. Will stop the timeout error from being shown. */
1359
+ protected ignoreResponderTimeout: boolean = false
1364
1360
  /**The context menu wich is the source of this instance. */
1365
1361
  menu:ODContextMenu
1366
1362
  /**The user who triggered this context menu. */
@@ -1388,19 +1384,18 @@ export class ODContextMenuResponderInstance extends ODBaseResponderInstance {
1388
1384
  else throw new ODSystemError("ODContextMenuResponderInstance: Invalid context menu type. Should be of the type User/Message!")
1389
1385
 
1390
1386
  setTimeout(async () => {
1391
- if (!this.didReply){
1392
- try {
1393
- if (!errorCallback){
1394
- this.reply({id:new ODId("opendiscord:unknown-error"), ephemeral:true, message:{
1395
- content:":x: **Something went wrong while replying to this context menu!**"
1396
- }})
1397
- }else{
1398
- await errorCallback(this,"context-menu")
1399
- }
1400
-
1401
- }catch(err){
1402
- process.emit("uncaughtException",err)
1387
+ if (this.ignoreResponderTimeout) return
1388
+ try {
1389
+ if (!errorCallback){
1390
+ this.reply({id:new ODId("opendiscord:unknown-error"), ephemeral:true, message:{
1391
+ content:":x: **Something went wrong while replying to this context menu!**"
1392
+ }})
1393
+ }else{
1394
+ await errorCallback(this,"context-menu")
1403
1395
  }
1396
+
1397
+ }catch(err){
1398
+ process.emit("uncaughtException",err)
1404
1399
  }
1405
1400
  },timeoutMs ?? 2500)
1406
1401
  }
@@ -1411,11 +1406,11 @@ export class ODContextMenuResponderInstance extends ODBaseResponderInstance {
1411
1406
  const finalMessage = this.getMessageFromBuildResult(build,"interaction")
1412
1407
  if (this.interaction.replied || this.interaction.deferred){
1413
1408
  const sent = await this.interaction.editReply(finalMessage)
1414
- this.didReply = true
1409
+ this.ignoreResponderTimeout = true
1415
1410
  return {success:true,message:sent}
1416
1411
  }else{
1417
1412
  const sent = await this.interaction.reply(finalMessage)
1418
- this.didReply = true
1413
+ this.ignoreResponderTimeout = true
1419
1414
  return {success:true,message:await sent.fetch()}
1420
1415
  }
1421
1416
  }catch{
@@ -1428,7 +1423,7 @@ export class ODContextMenuResponderInstance extends ODBaseResponderInstance {
1428
1423
  const finalMessage = this.getMessageFromBuildResult(build,"interaction")
1429
1424
  if (this.interaction.replied || this.interaction.deferred){
1430
1425
  const sent = await this.interaction.editReply(finalMessage)
1431
- this.didReply = true
1426
+ this.ignoreResponderTimeout = true
1432
1427
  return {success:true,message:await sent.fetch()}
1433
1428
  }else throw new ODSystemError("Unable to update context menu interaction!")
1434
1429
  }catch{
@@ -1437,19 +1432,19 @@ export class ODContextMenuResponderInstance extends ODBaseResponderInstance {
1437
1432
  }
1438
1433
  /**Defer this context menu. */
1439
1434
  async defer(type:"reply", ephemeral:boolean){
1435
+ this.ignoreResponderTimeout = true
1440
1436
  if (this.interaction.deferred || this.interaction.replied) return false
1441
1437
  if (type == "reply"){
1442
1438
  const msgFlags: number[] = ephemeral ? [discord.MessageFlags.Ephemeral] : []
1443
1439
  await this.interaction.deferReply({flags:msgFlags})
1444
1440
  }
1445
- this.didReply = true
1446
1441
  return true
1447
1442
  }
1448
1443
  /**Show a modal as reply to this context menu. */
1449
1444
  async modal(modal:ODModalBuildResult){
1445
+ this.ignoreResponderTimeout = true
1450
1446
  if (this.interaction.deferred || this.interaction.replied) return false
1451
1447
  await this.interaction.showModal(modal.modal)
1452
- this.didReply = true
1453
1448
  return true
1454
1449
  }
1455
1450
  }
@@ -1,6 +1,7 @@
1
1
  import * as fs from "fs"
2
2
  import ansis from "ansis"
3
3
  import * as api from "../api/index.js"
4
+ import * as discord from "discord.js"
4
5
 
5
6
  /**## sharedFuses `utility variable`
6
7
  * All shared fuses from Open Discord. Please use `opendiscord.sharedFuses` instead!
@@ -166,6 +167,27 @@ export function trimEmojis(text:string){
166
167
  return text.replace(/(\p{Extended_Pictographic}(?:\uFE0F|\uFE0E)?(?:\u200D\p{Extended_Pictographic}(?:\uFE0F|\uFE0E)?)*)/gu,"")
167
168
  }
168
169
 
170
+ /**## getMessageFromBuildResult `utility function`
171
+ * Get the final `messageCreateOptions` from a returned build result from builders/components.
172
+ */
173
+ export function getMessageFromBuildResult(build:api.ODMessageBuildResult|api.ODMessageComponentBuildResult,type:"interaction"|"message"){
174
+ const msgFlags: number[] = []
175
+ let msgData: discord.MessageCreateOptions
176
+ if ('message' in build){
177
+ //USING BUILDERS (deprecated)
178
+ msgData = build.message
179
+ if (build.ephemeral) msgFlags.push(discord.MessageFlags.Ephemeral)
180
+ }else{
181
+ //USING COMPONENTS
182
+ msgData = build.msg
183
+ if (type == "interaction" && build.ephemeral) msgFlags.push(discord.MessageFlags.Ephemeral) //disabled with regular messages
184
+ if (build.componentsV2) msgFlags.push(discord.MessageFlags.IsComponentsV2)
185
+ if (build.supressEmbeds) msgFlags.push(discord.MessageFlags.SuppressEmbeds)
186
+ if (build.supressNotifications) msgFlags.push(discord.MessageFlags.SuppressNotifications)
187
+ }
188
+ return Object.assign(msgData,{flags:msgFlags})
189
+ }
190
+
169
191
  /**## easterEggs `utility object`
170
192
  * Object containing data for Open Ticket easter eggs.
171
193
  */