Skip to content

Commit 87d5be4

Browse files
Merge pull request #58 from praaachii4596/feature/faq-number-dropdown
Add FAQ number input and dropdown selection features
2 parents 8f94d88 + 7920882 commit 87d5be4

File tree

1 file changed

+69
-11
lines changed

1 file changed

+69
-11
lines changed

index.js

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const {
77
ActionRowBuilder,
88
ButtonBuilder,
99
ButtonStyle,
10+
StringSelectMenuBuilder,
1011
} = require("discord.js");
1112
const stringSimilarity = require("string-similarity");
1213
const fs = require("fs");
@@ -68,6 +69,26 @@ function getFaqPageContent(page, faqs) {
6869
return content;
6970
}
7071

72+
// Helper to create a select menu for a page of FAQs
73+
function getFaqSelectMenu(page, faqs) {
74+
const start = page * FAQ_PAGE_SIZE;
75+
const end = start + FAQ_PAGE_SIZE;
76+
const slice = faqs.slice(start, end);
77+
78+
const options = slice.map((f, i) => ({
79+
label: f.question.length > 100 ? f.question.slice(0, 97) + "..." : f.question,
80+
description: `Question #${start + i + 1}`,
81+
value: `${start + i + 1}`, // question number as string (1-based)
82+
}));
83+
84+
return new ActionRowBuilder().addComponents(
85+
new StringSelectMenuBuilder()
86+
.setCustomId("faq_select_question")
87+
.setPlaceholder("Select a question to get its answer")
88+
.addOptions(options)
89+
);
90+
}
91+
7192
const serverId = "1378813132788727970";
7293
const TARGET_GUILD_ID = "1378813132788727970";
7394

@@ -116,21 +137,55 @@ client.once("ready", async () => {
116137

117138
client.on(Events.InteractionCreate, async (interaction) => {
118139
try {
140+
if (interaction.isStringSelectMenu()) {
141+
if (interaction.customId === "faq_select_question") {
142+
const selectedValue = interaction.values[0];
143+
const qNum = parseInt(selectedValue, 10);
144+
if (isNaN(qNum) || qNum < 1 || qNum > faqs.length) {
145+
await interaction.reply({ content: "❌ Invalid question selection.", ephemeral: true });
146+
return;
147+
}
148+
const faq = faqs[qNum - 1];
149+
await interaction.reply({
150+
content: `**Q${qNum}. ${faq.question}**\n\n${faq.answer}`,
151+
ephemeral: true,
152+
});
153+
return;
154+
}
155+
}
156+
119157
if (interaction.isChatInputCommand()) {
120158
const userQuestion = interaction.options.getString("question");
121-
console.log("userque: ", userQuestion);
122159

123160
if (interaction.commandName === "faq") {
124161
if (!userQuestion) {
125162
throw new Error("No question provided");
126163
}
127164

128-
// Handle paginated all commands
165+
// Check if input is a number representing FAQ index
166+
const trimmed = userQuestion.trim();
167+
const numberMatch = trimmed.match(/^(\d{1,2})$/);
168+
169+
if (numberMatch) {
170+
const qNum = parseInt(numberMatch[1], 10);
171+
if (qNum >= 1 && qNum <= faqs.length) {
172+
const match = faqs[qNum - 1];
173+
await interaction.reply(`**Q${qNum}. ${match.question}**\n\n${match.answer}`);
174+
return;
175+
} else {
176+
await interaction.reply(
177+
`❌ Invalid question number. Please enter a number between 1 and ${faqs.length}.`
178+
);
179+
return;
180+
}
181+
}
182+
183+
// --- "all commands" => paginated list with select menu
129184
if (userQuestion.toLowerCase().includes("all commands")) {
130185
const totalPages = Math.ceil(faqs.length / FAQ_PAGE_SIZE);
131186
const page = 0;
132187

133-
const row = new ActionRowBuilder().addComponents(
188+
const rowPagination = new ActionRowBuilder().addComponents(
134189
new ButtonBuilder()
135190
.setCustomId(`faq_prev_${page}`)
136191
.setLabel("Previous")
@@ -143,19 +198,18 @@ client.on(Events.InteractionCreate, async (interaction) => {
143198
.setStyle(ButtonStyle.Primary)
144199
.setDisabled(totalPages <= 1)
145200
);
201+
const rowSelectMenu = getFaqSelectMenu(page, faqs);
146202

147203
await interaction.reply({
148204
content: `**📋 FAQ List (Page ${
149205
page + 1
150-
}/${totalPages}):**\n\n${getFaqPageContent(
151-
page,
152-
faqs
153-
)}\n\n*Use \`/faq\` and start typing your question to get an instant answer!*`,
154-
components: [row],
206+
}/${totalPages}):**\n\n${getFaqPageContent(page, faqs)}\n\n*Select a question below, or type \`/faq question:<number>\` to get an answer!*`,
207+
components: [rowPagination, rowSelectMenu],
155208
});
156209
return;
157210
}
158211

212+
// --- Fuzzy match/autocomplete fallback ---
159213
const questions = faqs.map((faq) => faq.question);
160214

161215
const { bestMatch, bestMatchIndex } = stringSimilarity.findBestMatch(
@@ -399,7 +453,7 @@ client.on(Events.InteractionCreate, async (interaction) => {
399453
if (page < 0) page = 0;
400454
if (page >= totalPages) page = totalPages - 1;
401455

402-
const row = new ActionRowBuilder().addComponents(
456+
const rowPagination = new ActionRowBuilder().addComponents(
403457
new ButtonBuilder()
404458
.setCustomId(`faq_prev_${page}`)
405459
.setLabel("Previous")
@@ -413,14 +467,16 @@ client.on(Events.InteractionCreate, async (interaction) => {
413467
.setDisabled(page === totalPages - 1)
414468
);
415469

470+
const rowSelectMenu = getFaqSelectMenu(page, faqs);
471+
416472
await interaction.update({
417473
content: `**📋 FAQ List (Page ${
418474
page + 1
419475
}/${totalPages}):**\n\n${getFaqPageContent(
420476
page,
421477
faqs
422-
)}\n\n*Use \`/faq\` and start typing your question to get an instant answer!*`,
423-
components: [row],
478+
)}\n\n*Select a question below, or type \`/faq question:<number>\` to get an answer!*`,
479+
components: [rowPagination, rowSelectMenu],
424480
});
425481
});
426482

@@ -432,6 +488,8 @@ client.login(process.env.BOT_TOKEN).catch((error) => {
432488
app.use("/docs", express.static(path.join(__dirname, "views")));
433489
app.use("/docs", documentationRoute);
434490

491+
435492
app.listen(3000, () => {
436493
console.log(`🚀 Running at http://localhost:3000/docs`);
437494
});
495+

0 commit comments

Comments
 (0)