Adding buttons to an application sent to specified applicationChannelId - discord

Yes I know TLDR but I would appreciate the help
Ok I have this wall of code below I use for applications
It uses a button to start the application (asking questions)
and after the application is filled in it sends that application to a specified applicationChannelId
is there any way I could add buttons to the application that was sent to the applicationChannelId to accept or deny members?
Accept would add a role by id and sends a message to the original applicant
//Not the code I tried using just an example for what the Accept button would do
//
let teamRole = message.guild.roles.cache.find(role => role.id == "761996603434598460")
member.roles.add(teamRole)
member.send("You have been accepted into the team")
Deny would send a message to the original applicant
I have tried doing this for the past few days but just can't get it to work it either does nothing or breaks everything
I have removed some info from the code below to make it shorter
Code for my button I already use to start the application for an applicant
client.on("message", async (message) => {
const reqEmbed = {
color: 0xed5181,
title: 'Blind Spot Team Requirements',
url: 'link',
author: {
name: '',
icon_url: '',
url: '',
},
description: '',
thumbnail: {
url: '',
},
fields: [{
"name": `Read through these Requirements`,
"value": `- requirments will go here`,
}, ],
image: {
url: '',
},
footer: {
text: 'Blind Spot est 2019',
icon_url: 'link',
},
};
//
// Don't reply to bots
let admins = ['741483726688747541', '741483726688747541'];
if (message.content.startsWith(`#blindspot`)) {
message.delete();
const amount = message.content.split(" ")[1];
if (!admins.includes(message.author.id)) {
message.reply("You do not have permission to do that!");
return;
}
// Perform raw API request and send a message with a button,
// since it isn't supported natively in discord.js v12
client.api.channels(message.channel.id).messages.post({
data: {
embeds: [reqEmbed],
components: [{
type: 1,
components: [{
type: 2,
style: 4,
label: "Apply",
// Our button id, we can use that later to identify,
// that the user has clicked this specific button
custom_id: "send_application"
}]
}]
}
});
}
});
Rest of code that handles questions and sends application to applicationChannelId when complete
// Channel id where the application will be sent
const applicationChannelId = "652099170835890177";
// Our questions the bot will ask the user
const questions = ["These are the questions but have deleted them to make this shorter",];
// Function that will ask a GuildMember a question and returns a reply
async function askQuestion(member, question) {
const message = await member.send(question);
const reply = await message.channel.awaitMessages((m) => {
return m.author.id === member.id;
}, {
time: 5 * 60000,
max: 1
});
return reply.first();
}
client.ws.on("INTERACTION_CREATE", async (interaction) => {
// If component type is a button
if (interaction.data.component_type === 2) {
const guildId = interaction.guild_id;
const userId = interaction.member.user.id;
const buttonId = interaction.data.custom_id;
const member = client.guilds.resolve(guildId).member(userId);
if (buttonId == "send_application") {
// Reply to an interaction, so we don't get "This interaction failed" error
client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 4,
data: {
content: "I have started the application process in your DM's.",
flags: 64 // make the message ephemeral
}
}
});
try {
// Create our application, we will fill it later
const application = new MessageEmbed()
.setTitle("New Application")
.setDescription(`This application was submitted by ${member}/${member.user.tag}`)
.setFooter("If the #Username doesn't appear please go to general chat and scroll through the member list")
.setColor("#ED4245");
const cancel = () => member.send("Your application has been canceled.\n**If you would like to start your application again Click on the Apply button in** <#657393981851697153>");
// Ask the user if he wants to continue
const reply = await askQuestion(member, "Please fill in this form so we can proceed with your tryout.\n" + "**Type `yes` to continue or type `cancel` to cancel.**");
// If not cancel the process
if (reply.content.toLowerCase() != "yes") {
cancel();
return;
}
// Ask the user questions one by one and add them to application
for (const question of questions) {
const reply = await askQuestion(member, question);
// The user can cancel the process anytime he wants
if (reply.content.toLowerCase() == "cancel") {
cancel();
return;
}
application.addField(question, reply);
}
await askQuestion(member, "Would you like to submit your Application?\n" + "**Type `yes` to get your Application submitted and reviewed by Staff Members.**");
// If not cancel the process
if (reply.content.toLowerCase() != "yes") {
cancel();
return;
}
// Send the filled application to the application channel
client.channels.cache.get(applicationChannelId).send(application);
} catch {
// If the user took too long to respond an error will be thrown,
// we can handle that case here.
member.send("You took too long to respond or Something went wrong, Please contact a Staff member\n" + "The process was canceled.");
}
}
}
});
at this point I just feel like not even doing this and keep it as is because its driving me insane

You very well can! just send it as you send your normal buttons!
const {
MessageButton,
MessageActionRow
} = require("discord.js"),
const denybtn = new MessageButton()
.setStyle('DANGER')
.setEmoji('āŒ')
.setCustomId('deny')
const acceptbtn = new MessageButton()
.setStyle('SUCCESS')
.setEmoji('āœ”')
.setCustomId('accept')
client.channels.cache.get(applicationChannelId).send({
embeds: [application],
components: [new MessageActionRow().addComponents["acceptbtn", "denybtn"]]
});
const collector = msg.createMessageComponentCollector({
time: 3600000,
errors: ["time"],
});
await collector.on("collect", async (r) => {
if (r.user.id !== message.author.id)
return r.reply({
content: "You may not accept/ deny this application",
ephemeral: true,
});
if (r.customId === "acceptbtn") {
let teamRole = message.guild.roles.cache.find(role => role.id == "761996603434598460")
member.roles.add(teamRole)
member.send("You have been accepted into the team")
}
if (r.customId === "denybtn") {
member.send("You have been rejected");
}
});
NOTE: Please be mindful that since your question lacks the functions / method definitions you are using I have used discord.js v13's methods, you may update your discord.js version and the code will work as intended ALTHOUGH the component collector's functions have been directly copy pasted from your question and in some instances such as member#send member is not defined, so please take this as an example and I urge you to write the code instead of copy pasting directly!

Related

Discord.js v12.5.3 is there a way I could add role(s) on interaction?

I am 90% done with my application system but I am missing one thing
I am trying to add roles when someone applies,
I tried doing it with this
let teamRole = message.guild.roles.cache.find(role => role.id == "761996603434598460")
member.roles.add(teamRole)
but it does not add the roles (I don't get any errors doing it)
is there any way I can do it with the code below for the interaction?
client.ws.on("INTERACTION_CREATE", async (interaction) => {
// If component type is a button
if (interaction.data.component_type === 2) {
const guildId = interaction.guild_id;
const userId = interaction.member.user.id;
const buttonId = interaction.data.custom_id;
const member = client.guilds.resolve(guildId).member(userId);
if (buttonId == "send_application") {
// Reply to an interaction, so we don't get "This interaction failed" error
client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 4,
data: {
content: "I have started the application process in your DM's.",
flags: 64 // make the message ephemeral
}
}
});
I would appreciate the help with this
When you add a role it should be a snowflake value, so you should add using the ID and not the role it self
Incorrect:
let teamRole = message.guild.roles.cache.find(role => role.id == "761996603434598460")
member.roles.add(teamRole)
Correct:
// using the ID Directly
member.roles.add('761996603434598460')

Bot readout for who used a command

Wanting to have a readout channel for my bot to keep track of what happens, just like a second console log. Want to be able to have it read out in the message the username of the person who used the command. Any ideas? Also, in a similar note, is there a way to copy the console readout and possibly just paste that instead?
var Scraper = require('images-scraper');
const google = new Scraper({
puppeteer: {
headless: true
},
})
module.exports = {
name: 'image',
description: 'Google image scraper',
async execute(message, args){
const readout = message.guild.channels.cache.find(c => c.name === 'bot-readout');
const image_query = args.join(' ');
if(!image_query) return message.channel.send('Please enter a valid image search.');
const image_results = await google.scrape(image_query, 1);
message.channel.send(image_results[0].url);
readout.send('Image sent');
}
}
I think you want
message.author.username (It gives username who sent the message)
or message.member (it gives user as a guildmember)
Just access the author property of the message object and include it via a template string into the message:
readout.send(`Image sent to ${message.author.username}`);
Ended up doing an embed system in a separate channel on my discord.
const Discord = require('discord.js');
module.exports = {
name: 'suggestionlog',
description: 'logs suggestion',
execute(message){
const readout = message.guild.channels.cache.find(c => c.name === 'bot-readout');
const embed = new Discord.MessageEmbed()
.setColor('FADF2E')
.setTitle(message.channel.name)
.setAuthor(message.author.username, message.author.displayAvatarURL({ dynamic: true }))
.setDescription(message);
readout.send(embed)
.catch((err)=>{
throw err;
});
}
}

QuickDB + Discordjs 'Gameboard' Pinned Messages System Not Working (Similar To Carl-Bot's 'Starboard')

I was programming a discordjs bot with my friends, when we decided to make a gameboard. Basically, its a channel in which every message that gets 2 :video_game: reactions gets put there (Like 'best messages'). However, there is a problem and I can't seem to fix it. Here is my code:
client.on('messageReactionAdd', (reaction, user) => {
if (user.bot) return;
console.log(reaction);
if (reaction.emoji.name == 'šŸŽ®') {
if (reaction.count == 2) {
if (db.has('gameboard') == false) {
gameboard = db.table('gameboard');
};
if (db.get('gameboard', {id: reaction.author.id}) == null) {
db.add('gameboard', {
id: reaction.message.author.id,
username: reaction.message.author.username,
avatar: reaction.message.author.avatar,
content: reaction.message.content
});
}
msg = db.get('gameboard', {id: reaction.author.id});
embed = new Discord.MessageEmbed()
.setColor('RANDOM')
.setDescription(message.content)
.setAuthor(message.username, `https://cdn.discordapp.com/avatars/${msg.id}/${msg.author}.png?size=128`)
client.channels.cache.get('813807201042169926').send(embed);
};
};
});
I already have QuickDB setup with the json.sqlite file. The whole code is open-source here.

Audit Log Executor Is Incorrect

This bot I am making is tasked with logging when a user receives a role and when a user has a role removed. It prints that to a desired channel. Additionally I want the bot to send data to a database for the user when they receive a certain role. This part is working. I want the code to IGNORE the database addition/removal when the bot is the one adding or removing roles. This part is not working correctly. The way I have it setup is to check the audit logs to see who the executor of the action was. The intended effect is that if the executor's username matches my bot's username, the code does not run. However, even when the bot adds or removes a user's role, and the audit log visibly shows the bot as the one completing the action, when logging the entry to the console it displays myself, not the bot, as the executor.
client.on("guildMemberUpdate", async function(oldMember, newMember){ //When a user has their roles changed (added or removed)
const entry = await oldMember.guild.fetchAuditLogs({type: 'MEMBER_UPDATE'}).then(audit => audit.entries.first()) //Find audit logs pertaining to member update
console.log(entry) //Print the data to the console
if (entry.executor.username == "PolarBot") { //If the executor of the role addition is the bot then do nothing
return;
}
else { //Otherwise execute the code
if (oldMember.author == client.user) { // Prevent bot from responding to its own messages
return
}
if (oldMember.roles.size < newMember.roles.size) { //If the old member has less roles than the new member
currency.add(oldMember.user.id, 1); //Establish user in the database
const target = oldMember.user.id //Establish target ID for the database
for (const role of newMember.roles.map(x => x.id)) { //Find the new role
const item = await CurrencyShop.findOne({ where: { name: { [Op.like]: `${oldMember.guild.roles.get(role).name}` } } }); //Set item to be the role added
const user = await Users.findOne({ where: { user_id: target } }); //Find the target location in the database and name it user
const items = await user.getItems(); //Ignore this
user.addItem(item); //Add role to the database for that uesr
if (!oldMember.roles.has(role)) { //Check to see if the old member does not have the role
oldMember.guild.channels.find(channel => channel.name === "change-logging").send({embed: { //Send log message to the correct channel
color: 16723502,
title: "**User Roles Updated:**",
description: oldMember.user.tag,
fields: [
{
name: "**New Role(s)**",
value: `${oldMember.guild.roles.get(role).name}`,
inline: true
}
],
timestamp: new Date(),
}})
}
}
}
if (oldMember.roles.size > newMember.roles.size) {
currency.add(oldMember.user.id, 1);
const target = oldMember.user.id
for (const role of oldMember.roles.map(x => x.id)) {
const item = await CurrencyShop.findOne({ where: { name: { [Op.like]: `${oldMember.guild.roles.get(role).name}` } } });
const user = await Users.findOne({ where: { user_id: target } });
const items = await user.getItems();
user.removeItem(item); //Subtract role from the data base
if (!newMember.roles.has(role)) {
oldMember.guild.channels.find(channel => channel.name === "change-logging").send({embed: {
color: 16723502,
title: "**User Roles Updated:**",
description: oldMember.user.tag,
fields: [
{
name: "**Removed Role(s)**",
value: `${oldMember.guild.roles.get(role).name}`,
inline: true
}
],
timestamp: new Date(),
}})
}
}
}
}
});
Expected Result: When logging "entry" to the console the executor section should read my bot's username.
Actual Result: I am listed as the executor.
Link to console output:
Turns out Iā€™m a bit silly and the actual audit log event I wanted to call was MEMBER_ROLE_UPDATE not MEMBER_UPDATE

Where to put Discord JS Bot Presence code?

So I was trying to put code into my Discord bot to give it a custom status for users to see, then when I found the code I had no idea where to put it.
Here's the code: where should I put it?
* Sets the full presence of the client user.
* #param {PresenceData} data Data for the presence
* #returns {Promise<ClientUser>}
* #example
* // Set the client user's presence
* client.user.setPresence({ game: { name: 'with discord.js' }, status: 'idle' })
* .then(console.log)
* .catch(console.error);
*/
setPresence(data) {
return new Promise(resolve => {
let status = this.localPresence.status || this.presence.status;
let game = this.localPresence.game;
let afk = this.localPresence.afk || this.presence.afk;
if (!game && this.presence.game) {
game = {
name: this.presence.game.name,
type: this.presence.game.type,
url: this.presence.game.url,
};
}
This code above belongs to the ClientUser.js file. It might belong to other files like Presence.js
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
client.user.setPresence({
status: 'online',
activity: {
name: ".help",
type: "PLAYING"
}
});
});
The status can be online, idle, dnd, or invisible. (dnd is Do not disturb)
The other variable here is activity. It is a group of two variables: name and type.
The name is what the bot is doing. This is a string of your choice. The type is the other thing that will help it display as. It can be "PLAYING", "STREAMING", "WATCHING", "LISTENING", and "CUSTOM_STATUS".
You can put it anywhere but most likely you want to put it into your ready event like
client.on('ready', () => {
client.user.setPresence({ game: { name: 'with discord.js' }, status: 'idle' })
console.log(`${client.user.username} is up and running!`);
})

Resources