What we intend to do:
Replies with dropdown Menu if data from database has more than 1 item And responds accordingly with that value chosen from drop down.
The Problem:
Since we have modularized the code (According to discordjs guide) we are not able to receive interactions that are not commandInteractionThe project is initialised with Typescript and we are trying to build a modularized discord bot. The current project structure
├── package.json
├── src
│ ├── api
│ │ ├── auth.ts
│ │ ├── databaseCalls.ts
│ │ └── store.ts
│ ├── commands
│ │ └── store.ts
│ ├── events
│ │ ├── interactionCreate.ts
│ │ └── ready.ts
│ ├── index.ts
│ ├── lib
│ │ ├── embeds.ts
│ │ ├── env.ts
│ │ └── errors.ts
│ ├── models
│ │ └── user.model.ts
│ ├── services
│ │ ├── database.ts
│ │ └── deployCommands.ts
│ └── types
│ ├── common
│ │ ├── cookiejar.d.ts
│ │ └── discord.d.ts
│ └── index.ts
├── tsconfig.json
└── yarn.lock
// index.ts
// types for these are yet to be added
client.commands = new Collection();
const commandFiles = fs.readdirSync('./commands').filter((file) => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
client.commands.set(command.default.data.name, command);
}
const eventFiles = fs.readdirSync('./events').filter((file) => file.endsWith('.js'));
for (const file of eventFiles) {
const { default: event } = require(`./events/${file}`);
if (event.once) {
client.once(event.name, (...args) => event.execute(...args));
} else {
client.on(event.name, (...args) => event.execute(...args, client));
}
}
// events/interactionCreate.ts
import { Client, Interaction } from 'discord.js';
import { exceptionEmbed } from '../lib/embeds';
export default {
name: 'interactionCreate',
async execute(interaction: Interaction, client: Client) {
// This is the problem selectMenu interaction gets returned
if (!interaction.isCommand()) return;
const { default: command } = client.commands.get(interaction.commandName);
if (!command) return;
try {
await command.execute(interaction);
} catch (error) {
console.log(error);
await interaction.reply({ embeds: [exceptionEmbed()] });
}
},
};
// /commands/store.ts
import { SlashCommandBuilder } from '@discordjs/builders';
import {
CommandInteraction,
MessageActionRow,
MessageSelectMenu,
MessageSelectMenuOptions,
MessageSelectOptionData,
} from 'discord.js';
import { getUsers } from '../api/databaseCalls';
import { embedTemplate, notFoundEmbed } from '../lib/embeds';
import { getStore } from '../api/store';
export default {
data: new SlashCommandBuilder()
.setName('store'),
async execute(interaction: CommandInteraction) {
await interaction.reply({
embeds: [
embedTemplate(
'Please wait',
'We are working on it',
'https://c.tenor.com/FBeNVFjn-EkAAAAC/ben-redblock-loading.gif',
),
],
});
const discordId: string = interaction.user.id;
const users = await getUsers(discordId);
if (!users) {
await interaction.editReply({ embeds: [notFoundEmbed] });
return;
}
if (users.length > 1) {
let options: MessageSelectOptionData[] = [];
users.map((user, index) => {
options.push({
label: user.username,
value: index.toString(),
});
});
const row = new MessageActionRow().addComponents(
new MessageSelectMenu().setCustomId('accountselector').setPlaceholder('Nothing selected').addOptions(options),
);
interaction.editReply({ components: [row] });
// I need to get value from this dropdown and reply accordingly
return;
}
// Ignore these
const skinEmbeds = await getStore(users[0].username, users[0].password, users[0].region);
await interaction.editReply({ embeds: skinEmbeds });
return;
},
};