How to add buttons to embed pages discord.js - javascript

I've been trying to add buttons to my slash command to make embed pages. All the info I've been able to find has either just been on buttons (not buttons + slash commands) or needs to be done within the index file and not done with a command handler. I've tried adding an await to the interaction.reply but it sends an error that it needs to be within an async function. I'm not entirely sure how async/await works so I couldn't work much more on that if that would be the proper way to solve my issue. How would I collect the button interaction within a command handled file to edit the embeds on button click? This is the guide I used to create the initial command handler.
Here's my current info.js file.
const { SlashCommandBuilder } = require("#discordjs/builders");
const Discord = require("discord.js");
const info = require("./info.json");
module.exports = {
data: new SlashCommandBuilder()
.setName("cinfo")
.setDescription("Shows AniGame card info")
.addStringOption(option =>
option
.setName("name")
.setDescription("Enter the name of a card")
.setRequired(false)
),
async execute(interaction) {
const msg = interaction.options.getString("name").toLowerCase();
function cinfo(
name,
info,
stats,
talent,
image,
sr1,
sr2,
sr3,
srt,
ur1,
ur2,
ur3,
urt
) {
const base = new Discord.MessageEmbed()
.setTitle(name)
.setColor(0xffd1dc)
.setDescription(info)
.addField("__Card Stats__", stats)
.addField("Talent", talent)
.setImage(image);
const sr = new Discord.MessageEmbed()
.setTitle(name + " | Level 50")
.setColor(0xffd1dc)
.addField("__SR Evo 1__", sr1, true)
.addField("__SR Evo 2__", sr2, true)
.addField("__SR Evo 3__", sr3, true)
.addField("Talent", srt)
.setImage(image);
const ur = new Discord.MessageEmbed()
.setTitle(name + " | Level 60")
.setColor(0xffd1dc)
.addField("__UR Evo 1__", ur1, true)
.addField("__UR Evo 2__", ur2, true)
.addField("__UR Evo 3__", ur3, true)
.addField("Talent", urt)
.setImage(image);
const row = new Discord.MessageActionRow().addComponents(
new Discord.MessageButton()
.setCustomId("backward")
.setStyle("PRIMARY")
.setEmoji("⬅️"),
new Discord.MessageButton()
.setCustomId("forward")
.setStyle("PRIMARY")
.setEmoji("➡️"),
new Discord.MessageButton()
.setCustomId("delete")
.setStyle("DANGER")
.setEmoji("🗑️")
);
const pages = [base, sr, ur];
interaction.reply({ embeds: [base], components: [row] });
// await interaction.editReply()
}
// location 1
if (
msg === "itaru hashida" ||
msg === "itaru" ||
msg === "hashida"
) {
cinfo(
info.Itaru_Hashida[0],
info.Itaru_Hashida[1],
info.Itaru_Hashida[2],
info.Itaru_Hashida[3],
info.Itaru_Hashida[4],
info.Itaru_Hashida[5],
info.Itaru_Hashida[6],
info.Itaru_Hashida[7],
info.Itaru_Hashida[8],
info.Itaru_Hashida[9],
info.Itaru_Hashida[10],
info.Itaru_Hashida[11],
info.Itaru_Hashida[12]
);
}
}
};

There is more than one way to do this.
You can use the interactionCreate event. Whenever the event is emitted, you can use <interaction>.isButton() to check if the interaction is from a button. If so, you can edit the <interaction>.message with the <interaction>.message.edit method.
You can also use an InteractionCollector (How to use | Example).

Here are some solutions I found for your question:
Solution 1: Package
I have created a package called discord.js-util that does various things like create embed pages. You could install it or just copy the source code here.
Solution 2: Create your own
As #Qreepex said you can create your own by using a interactionCollector and then using the customId to check if it should to back or forward.

Related

Using client in other files than main file

I'm a very new discord.js coder. I have been trying to use this code in a different file, \modules\verifyForm.js, and it always comes up with client is not defined. I've had quite a large look around and it always comes up with something that is too outdated, something very advanced or something that just don't work.
I have a separate main file in \index.js in which this piece of code works. Client is defined in that file or course, but because you can't have two instances I can't re-define it. Am I just being dumb or is there a better way to do this. Would a collection or using exports help?
const { ActionRowBuilder, Events, InteractionType, ModalBuilder, TextInputBuilder, TextInputStyle, } = require('discord.js');
client.on(Events.InteractionCreate, async (interaction) => {
if (interaction.isButton()) {
if (interaction.customId === 'verification-button') {
const modal = new ModalBuilder()
.setCustomId('verification-modal')
.setTitle('Verify yourself')
.addComponents([
new ActionRowBuilder().addComponents(
new TextInputBuilder()
.setCustomId('verification-input')
.setLabel('Answer')
.setStyle(TextInputStyle.Short)
.setMinLength(0)
.setMaxLength(512)
.setPlaceholder('ABCDEF')
.setRequired(true),
),
]);
await interaction.showModal(modal);
}
}
if (interaction.type === InteractionType.ModalSubmit) {
if (interaction.customId === 'verification-modal') {
const response =
interaction.fields.getTextInputValue('verification-input');
interaction.channel(`Yay, your answer is submitted: "${response}"`);
}
}
});
I do have a separate embed with the button attached.
If you do have a way to get around using client or if you have a way to fix the error, thanks.
make the client a global variable so you can use it everywhere, basically global.client = new Client()

Why does using my code in replit instead of vsc give me different results when the code is the same?

I am trying to implement the discord.js button feature into my bot, not as a command but just to get the feel of it. I followed a tutorial and wrote a command for it, which i put in a file in my commands folder. The code for the command is below-
I ran the code in replit, and saw no errors. After this, i tried the command in discord but there was no response, and no error in the console.
const discord = require ("discord.js");
const { MessageButton } = require ("discord-buttons");
module.exports = {
name: 'smart',
aliases:[],
run: async (Client,message,args,prefix) => {
if(!message.content.startsWith(prefix)) return
const embed = new discord.MessageEmbed()
.setTitle("Are you smart?")
.setColour("BLUE")
const ye = new MessageButton()
.setStyle("green")
.setLabel("yes")
.setID("smart")
const nu = new MessageButton()
.setStyle("red")
.setLabel("no")
.setID("idiot")
message.channel.send("Hello",{
buttons: [yes,no],
embed: embed
})
}
};

Trying to make it so my command only works in one guild Discord.js

in discord.js i am trying to make it so that my code only executes if the user is in a specific guild, how would i go about doing this?
module.exports = client => {
const channelId = '798241375572328479'
const infoId = '<#798241375136776215>'
const serverId = '798241375098896414'
client.on('guildMemberAdd', (member) => {
console.log(member)
if (client.guild.id(serverId)) {
const message = `Welcome to **awbtawtnawtb** ${member.user}!\n Please take some time to read through ${infoId}. \nI have also Direct Messaged you some quick information`
const welcomeEmbed = new Discord.MessageEmbed()
.setDescription(message);
client.channels.cache.get(channelId).send(welcomeEmbed)
const welcomeDMEmbed = new Discord.MessageEmbed()
.setColor('#9000D2')
.setTitle(`Welcome To The awbeyvatw Discord ${member.user.tag}!`)
.setDescription(`\n\nBy joining this server you are abide by the #info-read rules. Breaking one of these rules will result in punishments accordingly.\nIf you require help create a ticket in #support\nIf you have any further concerns you may DM me #JohnDoe#5032 as a last resort!\n\nI Hope you enjoy your time!\n\n-JohnDoe`)
.setAuthor(``);
const welcomedmipEmbed = new Discord.MessageEmbed()
.setColor('#00F0FF')
.setTitle(`Server Address: wvawbattbvga`)
} else {
} console.log(`Didn't send message due to not being in the same guild!`)
You would use the comparison operator.
if (member.guild.id === serverId) {
// Your code
}

Trying to make a Discord bot write a msg when someone joins the server

The title pretty much sums it up, but I'll add some more info. I'm trying to make a bot that sends a msg when someone joins. That msg is going to be an embed with some of the info of the new account. The msg needs to be written on 2 different channels and also send a PM to the new user.
I've tried doing this but I don't know why it doesn't send the messages:
module.exports = (client) => {
const Discord = require("discord.js")
const moment = require("moment");
require('moment-duration-format');
moment.locale('es');
client.on("guildMemberAdd", (member) => {
const embedGMA = new Discord.MessageEmbed()
.setTitle("🟢 **NEW MEMBER**")
.setDescription('▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬')
.setThumbnail(member.avatarURL())
.addField('USER:',member.tag, true)
.addField('MEMBER:', member.user, true)
.addField('ID:', member.id, true)
.addField('ACCOUNT CREATED:', member.createdAt.toDateString(), true)
.setColor("GREEN")
.addField('NOW WE ARE ' + member.guild.memberCount + ' MEMBERS.', true )
.setTimestamp()
.setFooter(server.name, server.iconURL())
member.send("HERE GOES THE PM")
let channel1 = client.channels.cache.get('CHANNEL ID');
let channel2 = client.channels.cache.get('CHANNEL ID');
channel1.send({ embed : embedGMA})
channel2.send({ embed : embedGMA})
});
}
As far as I can tell you are trying to send an Embed inside an Embed because you declare an Embed here: "const embedGMA = new Discord.MessageEmbed()" and then try to send that as an Embed again here: "channel1.send({ embed : embedGMA})". See here for reference.
To fix it, just try this
EDIT: You need to put the code below into your index.js file (or whatever you named the file to start the bot)
const Discord = require("discord.js");
/* We can ignore this for the most part as this has nothing to do with the code below
const moment = require("moment");
require('moment-duration-format');
moment.locale('es'); */
client.on("guildMemberAdd", (member) => {
//here we declare a new Embed
const embedGMA = new Discord.MessageEmbed()
.setTitle("🟢 **NEW MEMBER**")
.setDescription('▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬')
.setThumbnail(member.user.displayAvatarURL()) //**
.addField('USER:', member.displayName, true) //**
.addField('MEMBER:', member.user, true)
.addField('ID:', member.id, true)
.addField('ACCOUNT CREATED:', member.createdAt.toDateString(), true) // This might give you trouble if you don't have this function defined somewhere
.setColor("GREEN")
.addField('NOW WE ARE ' + member.guild.memberCount + ' MEMBERS.', `\u200b`, true) //**
.setTimestamp()
.setFooter(server.name, server.iconURL()); // You need to define server somewhere
member.send("HERE GOES THE PM")
let channel1 = client.channels.cache.get('CHANNEL ID');
let channel2 = client.channels.cache.get('CHANNEL ID');
//here we just send the Embed
channel1.send(embedGMA);
channel2.send(embedGMA);
});
ps. I also corrected a few of your embed settings, I marked them with //**

General practice of having code after return statement - unreachable code

I have come a long way from when I first started learning to code however, this is one thing that has eluded me. I need to add a couple of things into an event on my bot however it can become unreachable if logging is disabled as it returns, what is the general way to do something like this?
const id = db.prepare(`SELECT channel FROM logging WHERE guildid = ${member.guild.id};`).get();
if (!id) return;
const logs = id.channel;
const logembed = new MessageEmbed()
.setAuthor('Member Joined', member.user.avatarURL())
.setDescription(`<#${member.user.id}> - ${member.user.tag}`)
.setColor(color)
.setFooter(`ID: ${member.user.id}`)
.setTimestamp();
bot.channels.cache.get(logs).send(logembed);
// Example
// If I do code here, but logs are disabled, it's unreachable as the above returns.
};
Would removing the return statement be a good way to do it?
const id = db.prepare(`SELECT channel FROM logging WHERE guildid = ${member.guild.id};`).get();
if (id) {
const logs = id.channel;
const logembed = new MessageEmbed()
.setAuthor('Member Joined', member.user.avatarURL())
.setDescription(`<#${member.user.id}> - ${member.user.tag}`)
.setColor(color)
.setFooter(`ID: ${member.user.id}`)
.setTimestamp();
bot.channels.cache.get(logs).send(logembed);
}

Categories