Skip to content

Commit 97202d9

Browse files
committed
initial gauntlet command
1 parent 1d1cf5f commit 97202d9

2 files changed

Lines changed: 109 additions & 1 deletion

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"dependencies": {
4444
"@libsql/client": "^0.17.0",
4545
"@retroachievements/api": "^2.6.0",
46-
"discord.js": "^14.21.0",
46+
"discord.js": "^14.26.4",
4747
"drizzle-orm": "0.44.3",
4848
"figlet": "^1.8.2",
4949
"youtube-search": "^1.1.6"
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import {MessageFlags, ModalBuilder, RadioGroupOptionBuilder, SlashCommandBuilder, TextInputStyle} from "discord.js";
2+
3+
import type {SlashCommand} from "../models";
4+
5+
const gauntletSlashCommand: SlashCommand = {
6+
data: new SlashCommandBuilder()
7+
.setName("gauntlet")
8+
.setDescription("Starts up an icon-gauntlet.")
9+
.addStringOption((option) => option
10+
.setName("url")
11+
.setDescription("URL of the game/hub you are updating")
12+
.setRequired(true)
13+
)
14+
.addStringOption((option) => option
15+
.setName("type")
16+
.setDescription("The type of gauntlet you want to run")
17+
.setRequired(true)
18+
.addChoices(
19+
{ name: 'Icon for Hub/Game', value: 'icon' },
20+
{ name: 'Collage for multiple Badges', value: 'collage' }
21+
)
22+
),
23+
24+
cooldown: 60, // 1 minute cooldown.
25+
26+
async execute(interaction, _client) {
27+
// options
28+
const url = interaction.options.getString("url", true);
29+
const type: 'icon' | 'collage' = interaction.options.getString("type", true) as 'icon' | 'collage';
30+
31+
const regex = /^https:\/\/retroachievements\.org\/(?:hub|game)\/\d+\/?$/;
32+
33+
if (!regex.test(url)) {
34+
await interaction.reply({ content: "Please specify a valid URL for the game/hub you want to change!", flags: MessageFlags.Ephemeral })
35+
return;
36+
}
37+
38+
const actualPollUrl = "gauntlet:" + url;
39+
40+
// Build our modal
41+
const modal = new ModalBuilder()
42+
.setCustomId(actualPollUrl)
43+
.setTitle("Icon Gauntlet Submission")
44+
.addLabelComponents(
45+
(originalLabel) => originalLabel
46+
.setLabel(type == 'icon' ? "Original Icon" : 'Current Icons')
47+
.setDescription(type == 'icon' ? "Leave blank to use current icon" : 'Upload a preview of what the icons currently look like')
48+
.setFileUploadComponent((file) => file
49+
.setCustomId("icon:original")
50+
.setMaxValues(1)
51+
.setRequired(false)
52+
.setRequired(type == 'collage')
53+
),
54+
55+
(contendersLabel) => contendersLabel
56+
.setLabel("Contenders")
57+
.setDescription("Upload each contender as its own image below")
58+
.setFileUploadComponent((file) => file
59+
.setCustomId("icon:contenders")
60+
.setMaxValues(10)
61+
.setRequired(true)
62+
),
63+
64+
(contactDevLabel) => contactDevLabel
65+
.setLabel("Have you contacted the dev regarding this?")
66+
.setDescription("This is required unless you have one of the exemptions. It will be added to your message for you.")
67+
.setRadioGroupComponent((radioGroup) => radioGroup
68+
.setCustomId("radiogroup-id")
69+
.addOptions(
70+
new RadioGroupOptionBuilder()
71+
.setLabel("Yes, they have been notified")
72+
.setDescription("Good job!")
73+
.setValue("notified"),
74+
new RadioGroupOptionBuilder()
75+
.setLabel("No, they have opted-out")
76+
.setDescription("Check the sheet to be sure!")
77+
.setValue("optout"),
78+
new RadioGroupOptionBuilder()
79+
.setLabel("No, they are inactive")
80+
.setDescription("No need to contact then")
81+
.setValue("inactive"),
82+
new RadioGroupOptionBuilder()
83+
.setLabel("No, this is a hub")
84+
.setDescription("Who would you contact anyway?")
85+
.setValue("hub")
86+
)
87+
),
88+
89+
(additionalInfoLabel) => additionalInfoLabel
90+
.setLabel("Additional Info")
91+
.setDescription("Anything else you want to add? You can also leave a message below this poll for more control.")
92+
.setTextInputComponent((textInput) => textInput
93+
.setCustomId("user:thoughts")
94+
.setStyle(TextInputStyle.Paragraph)
95+
.setRequired(false)
96+
.setPlaceholder("Your thoughts go here")
97+
)
98+
);
99+
100+
try {
101+
await interaction.showModal(modal);
102+
} catch (error) {
103+
console.error(error);
104+
}
105+
},
106+
};
107+
108+
export default gauntletSlashCommand;

0 commit comments

Comments
 (0)