Sourceae
Sourceae
DIAdiscord.js - Imagine a bot
Created by Sourceae on 3/6/2024 in #djs-questions
Commands not refreshing after being correctly deployed
Good evening. I'm developing a discord.js bot using typescript. I am having trouble using my deployed commands. To clarify, my bot integration successfully have the commands that I want to deploy but they are not visible within the channel I'm testing on. Here's my Commands.ts file to register the command and deploy them (public)
import { Client, Routes, SlashCommandBuilder } from "discord.js";
import { REST } from "@discordjs/rest"
import { readdirSync } from "fs";
import { join } from "path";
import { color } from "../functions";
import { SlashCommand } from "../types";

module.exports = (client : Client) => {
const slashCommands : SlashCommandBuilder[] = []

let slashCommandsDir = join(__dirname,"../slashCommands")

readdirSync(slashCommandsDir).forEach(file => {
if (!file.endsWith(".js")) return;
let command : SlashCommand = require(`${slashCommandsDir}/${file}`).default
slashCommands.push(command.command)
client.slashCommands.set(command.command.name, command)
})


const rest = new REST({version: "10"}).setToken(process.env.TOKEN);

rest.put(Routes.applicationCommands(process.env.CLIENT_ID), {
body: slashCommands.map(command => command.toJSON())
})
.then((data : any) => {
console.log(color("text", `🔥 Successfully loaded ${color("variable", data.length)} slash command(s)`))
}).catch(e => {
console.log(e)
})
}
import { Client, Routes, SlashCommandBuilder } from "discord.js";
import { REST } from "@discordjs/rest"
import { readdirSync } from "fs";
import { join } from "path";
import { color } from "../functions";
import { SlashCommand } from "../types";

module.exports = (client : Client) => {
const slashCommands : SlashCommandBuilder[] = []

let slashCommandsDir = join(__dirname,"../slashCommands")

readdirSync(slashCommandsDir).forEach(file => {
if (!file.endsWith(".js")) return;
let command : SlashCommand = require(`${slashCommandsDir}/${file}`).default
slashCommands.push(command.command)
client.slashCommands.set(command.command.name, command)
})


const rest = new REST({version: "10"}).setToken(process.env.TOKEN);

rest.put(Routes.applicationCommands(process.env.CLIENT_ID), {
body: slashCommands.map(command => command.toJSON())
})
.then((data : any) => {
console.log(color("text", `🔥 Successfully loaded ${color("variable", data.length)} slash command(s)`))
}).catch(e => {
console.log(e)
})
}
I find out that re-inviting the bot fixed the problem but I don't think this is a normal behaviour, since a public bot should have its command refreshed automatically in any server it's in, right ? Thanks for your help
7 replies
DIAdiscord.js - Imagine a bot
Created by Sourceae on 11/12/2023 in #djs-questions
"Interaction has already been acknowledged" after invoking a command twice in a row
Good morning, I've been encoutering an issue when trying to execute a command twice in a row. My button interaction collector is withing my command, with the code below :
const buttonsCollector =
interaction.channel.createMessageComponentCollector({
componentType: ComponentType.Button,
});

buttonsCollector.on('collect', async (buttonInteraction) => {
if (
buttonInteraction.user.id === interaction.user.id &&
buttonInteraction.customId.startsWith('Member')
) {
await handleButtons(
buttonInteraction,
member,
mulesSelectMenu,
buttons
);
} else {
await buttonInteraction.reply(
"Interaction impossible, tu n'es pas l'initiateur de la commande."
);
}
const buttonsCollector =
interaction.channel.createMessageComponentCollector({
componentType: ComponentType.Button,
});

buttonsCollector.on('collect', async (buttonInteraction) => {
if (
buttonInteraction.user.id === interaction.user.id &&
buttonInteraction.customId.startsWith('Member')
) {
await handleButtons(
buttonInteraction,
member,
mulesSelectMenu,
buttons
);
} else {
await buttonInteraction.reply(
"Interaction impossible, tu n'es pas l'initiateur de la commande."
);
}
In my handleButtons function, here's the case where I'm having the issue :
if (buttonInteraction.customId === 'MemberValidateEssaiButton') {
const validateEssaiMemberPseudo =
buttonInteraction.message.embeds[0].fields[1].value;
const updatedMember = await updateMember(
validateEssaiMemberPseudo,
'Rang',
'Membre'
);
const updatedEmbed = memberEmbed(updatedMember);
const updatedButtons = memberButtons(updatedMember);

await buttonInteraction.deferUpdate(); // this line raises the error
await buttonInteraction.editReply({
embeds: [updatedEmbed],
components: [updatedButtons],
});
if (buttonInteraction.customId === 'MemberValidateEssaiButton') {
const validateEssaiMemberPseudo =
buttonInteraction.message.embeds[0].fields[1].value;
const updatedMember = await updateMember(
validateEssaiMemberPseudo,
'Rang',
'Membre'
);
const updatedEmbed = memberEmbed(updatedMember);
const updatedButtons = memberButtons(updatedMember);

await buttonInteraction.deferUpdate(); // this line raises the error
await buttonInteraction.editReply({
embeds: [updatedEmbed],
components: [updatedButtons],
});
In addition, I see that the message still updates even if I get the error, so I'm a bit confused. Actually, note that once I clicked the button, my updatedButtons will not contain anymore the button that has been clicked. Could it be the reason of such an issue ? Thanks for your help
4 replies
DIAdiscord.js - Imagine a bot
Created by Sourceae on 11/3/2023 in #djs-questions
Edit two messages within the same button handler
Hello, I have a button handler that will call an external API, send an embed, and edit another message embed too, depending on the first sent embed. What is the correct way to make "sleep" for like 2 seconds my bot before editing the second embed ? I want to avoid any risk of editing with wrong data if the API call is too long
4 replies
DIAdiscord.js - Imagine a bot
Created by Sourceae on 8/9/2023 in #djs-questions
Extending EmbedBuilder class
Hello I created this Embed class to always have the same color and footer on my embeds. However, I'd like the setFooter to override only when it's not specified when calling the class. How could I make this ?
const { EmbedBuilder } = require('discord.js');
const { DateNow } = require('./utils');

class Embed extends EmbedBuilder {
constructor(...args) {
super(...args);

super.setColor('ffffff');

super.setFooter({
text: `Influence • ${DateNow}`,
iconURL:
'https://media.discordapp.net/attachments/xxxxxx.png',
});
}
}

module.exports = Embed;
const { EmbedBuilder } = require('discord.js');
const { DateNow } = require('./utils');

class Embed extends EmbedBuilder {
constructor(...args) {
super(...args);

super.setColor('ffffff');

super.setFooter({
text: `Influence • ${DateNow}`,
iconURL:
'https://media.discordapp.net/attachments/xxxxxx.png',
});
}
}

module.exports = Embed;
22 replies
DIAdiscord.js - Imagine a bot
Created by Sourceae on 8/8/2023 in #djs-questions
Emit command not emitting the event
Hello I'm making an 'Emit' command in order to test some event handlers. Here's my code :
// emit.js
data: new SlashCommandBuilder()
.setName('emit')
.setDescription('[DEV] Emit discord events for testing purposes')
.addUserOption((option) =>
option
.setName('user')
.setDescription('The usser to remove')
.setRequired(true)
),

async execute(interaction) {
const userId = interaction.options.getUser('user').id;
const memberToRemove = interaction.guild.members.cache.find(
(member) => member.user.id === userId
);

interaction.client.emit('GuildMemberRemove', memberToRemove);
await interaction.reply('GuildMemberRemove event emitted successfully.');
},
// emit.js
data: new SlashCommandBuilder()
.setName('emit')
.setDescription('[DEV] Emit discord events for testing purposes')
.addUserOption((option) =>
option
.setName('user')
.setDescription('The usser to remove')
.setRequired(true)
),

async execute(interaction) {
const userId = interaction.options.getUser('user').id;
const memberToRemove = interaction.guild.members.cache.find(
(member) => member.user.id === userId
);

interaction.client.emit('GuildMemberRemove', memberToRemove);
await interaction.reply('GuildMemberRemove event emitted successfully.');
},
// guildMemberRemove.js
name: Events.GuildMemberRemove,
async execute(member) {
console.log(`${member.user.username} left the guild.`
}
// guildMemberRemove.js
name: Events.GuildMemberRemove,
async execute(member) {
console.log(`${member.user.username} left the guild.`
}
The event is not triggered when I execute my command. Any idea please ?
37 replies
DIAdiscord.js - Imagine a bot
Created by Sourceae on 8/2/2023 in #djs-questions
Copying a slash command execution
Good evening, I was wondering if there's any way to copy paste a slash command execution, since my users will have to do them multiple times a day, instead of rewriting it every time, they could write it one time and then paste. Any ideas ? 😄
4 replies
DIAdiscord.js - Imagine a bot
Created by Sourceae on 7/8/2023 in #djs-questions
Reaction button sent only once
Hello there ! I would like to create a message embed with buttons attached to it like "Reaction Bots" do. I wonder how the bot will handle the click on the buttons since the message will only be sent once and never again. This message is supposed to be a welcome button where users click on it when they arrive on the server and it displays informations to them afterwards.
2 replies
DIAdiscord.js - Imagine a bot
Created by Sourceae on 7/4/2023 in #djs-questions
Multiselect dropdown list collector doesn't trigger
Good evening I have a first Dropdown list with 2 choices (maxValues = 1), then according to the choices it displays another dropdown list with 3 choices (maxValues = 3). The collector is working correctly for the first dropdown but for the second one when I select for example 2 values and then click away, it does not trigger the collector. Here's the code below :
async execute(interaction) {
const donjonOptions = createDonjonOptions();

const row = new ActionRowBuilder().addComponents(
new StringSelectMenuBuilder()
.setCustomId('dungeonSelect')
.setPlaceholder('Sélectionne un donjon')
.addOptions(donjonOptions)
);

const reply = await interaction.reply({
components: [row],
fetchReply: true,
});

const collector = reply.createMessageComponentCollector({
componentType: ComponentType.StringSelect,
});

const succesSelectMenu = new StringSelectMenuBuilder()
.setCustomId('succesSelect')
.setPlaceholder('Slectionnez les succès')
.setMinValues(1);

let selectedDungeon = '';
const selectedSucces = [];

collector.on('collect', async (menuInteraction) => {
if (menuInteraction.customId === 'dungeonSelect') {
// eslint-disable-next-line prefer-destructuring
selectedDungeon = menuInteraction.values[0];
const succesOptions = createSuccesOptions(selectedDungeon);

succesSelectMenu
.setMaxValues(succesOptions.length)
.addOptions(succesOptions);

const row = new ActionRowBuilder().addComponents(succesSelectMenu);

await menuInteraction.reply({
content: `Donjon sélectionné: ${selectedDungeon}`,
components: [row],
});
} else if (menuInteraction.customId === 'succesSelect') {
selectedSucces.push(...menuInteraction.values); // doesn't trigger
console.log(selectedSucces); // doesn't work
}
});
},
async execute(interaction) {
const donjonOptions = createDonjonOptions();

const row = new ActionRowBuilder().addComponents(
new StringSelectMenuBuilder()
.setCustomId('dungeonSelect')
.setPlaceholder('Sélectionne un donjon')
.addOptions(donjonOptions)
);

const reply = await interaction.reply({
components: [row],
fetchReply: true,
});

const collector = reply.createMessageComponentCollector({
componentType: ComponentType.StringSelect,
});

const succesSelectMenu = new StringSelectMenuBuilder()
.setCustomId('succesSelect')
.setPlaceholder('Slectionnez les succès')
.setMinValues(1);

let selectedDungeon = '';
const selectedSucces = [];

collector.on('collect', async (menuInteraction) => {
if (menuInteraction.customId === 'dungeonSelect') {
// eslint-disable-next-line prefer-destructuring
selectedDungeon = menuInteraction.values[0];
const succesOptions = createSuccesOptions(selectedDungeon);

succesSelectMenu
.setMaxValues(succesOptions.length)
.addOptions(succesOptions);

const row = new ActionRowBuilder().addComponents(succesSelectMenu);

await menuInteraction.reply({
content: `Donjon sélectionné: ${selectedDungeon}`,
components: [row],
});
} else if (menuInteraction.customId === 'succesSelect') {
selectedSucces.push(...menuInteraction.values); // doesn't trigger
console.log(selectedSucces); // doesn't work
}
});
},
Thank you for your help
12 replies