Trying to add a warning system to my mongodb, it works but says application didn't respond - discord.js

const {Client, CommandInteraction, MessageEmbed} = require("discord.js");
const db = require("../../Structures/Schemas/InfractionDB");
module.exports = {
name: "warnings",
description: "Give a warning",
permission: "ADMINISTRATOR",
options: [
{
name: "target",
description: "Select a target.",
type: "USER",
required: true
},
{
name: "reason",
description: "Provide a reason.",
type: "STRING",
required: true
},
{
name: "evidence",
description: "Provide evidence.",
type: "STRING",
required: false
},
],
/**
*
* #param {CommandInteraction} interaction
* #param {Client} client
*/
execute(interaction, client) {
const{guild, member, options} = interaction
const Target = options.getMember("target");
const Reason = options.getString("reason");
const Evidence = options.getString("evidence") || "None provided";
const Response = new MessageEmbed()
.setColor("RED")
.setAuthor({name: "MOD BOT", iconURL: guild.iconURL()});
db.findOne({GuildID: guild.id, UserID: Target.id}, async (err,data)=> {
if(err) throw err;
if(!data || !data.WarnData) {
data = new db({
GuildID: guild.id,
UserID: Target.id,
WarnData: [
{
ExecuterID: member.id,
ExecuterTag: member.user.tag,
TargetID: Target.id,
TargetTag: Target.user.tag,
Reason: Reason,
Evidence: Evidence,
Date: parseInt(interaction.createdTimestamp / 1000)
}
],
})
} else {
const WarnDataObject ={
ExecuterID: member.id,
ExecuterTag: member.user.tag,
TargetID: Target.id,
TargetTag: Target.user.tag,
Reason: Reason,
Evidence: Evidence,
Date: parseInt(interaction.createdTimestamp / 1000)
}
data.WarnData.push(WarnDataObject)
}
data.save()
});
Response.setDescription(`Warning Added: ${Target.user.tag} | ||${Target.id}||\n**Reason**: ${Reason}\n**Evidence**:${Evidence}`);
guild.channels.cache.get("946217387336818699").send({embeds:[Response]});
}}
originally this was routed to a different collection in my db. I've tried to convert it so I can see everything in one place. but it's taken me hours and don't seem to be getting anywhere. Like I said, the data is being stored on the db, but the Response is failing. Any ideas how to fix this? There are no errors in terminal

The error i think is that your application is taking too long to respond.
you have only 3 seconds to respose.
for this i would suggest that you execute you interaction as a async function
and you should use await before trying to find it in the database. because it can take some time to find the data in the database.
The data is store in database because it has no concern with the response time but the discord api wants a reply in 3 seconds or it will fail.
I have read your code. it seems okay.
i would suggest you to use the easier way instead of using the object or json form to create the commands.
SlashCommandBuilder from #discordjs/builders
its easy to use and simple.
here is an example of how easy it is if you use SlashCommandBuilder
const { SlashCommandBuilder } = require('#discordjs/builders');
const data = new SlashCommandBuilder()
.setName('gif')
.setDescription('Sends a random gif!')
.addStringOption(option =>
option.setName('category')
.setDescription('The gif category')
.setRequired(true)
.addChoice('Funny', 'gif_funny')
.addChoice('Meme', 'gif_meme')
.addChoice('Movie', 'gif_movie'));
you can install all the dependencies using
npm install discord.js #discordjs/rest discord-api-types

Related

discord.js api request command

const config = require(`${process.cwd()}/botconfig/config.json`)
var ee = require(`${process.cwd()}/botconfig/embed.json`)
const fetch = require("node-fetch");
const { MessageEmbed } = require(`discord.js`);
module.exports = {
//definition
name: "glifestats", //the name of the command
category: "⌨️ Programming", //the category this will be listed at, for the help cmd
aliases: [""], //every parameter can be an alias
cooldown: 4, //this will set it to a 4 second cooldown
usage: "glifestats <id>", //this is for the help command for EACH cmd
description: "check stats", //the description of the command
};
run: async (client, message, args, cmduser, text, prefix) => {
await interaction.deferReply();
const term = interaction.options.getString('term');
const query = new URLSearchParams({ term });
const { list } = await fetch(`https://api.gtaliferp.fr:8443/v1/extinction/profiles/main/${query}`)
.then(response => response.json());
}
When i try to do this command, it does nothing.
It needs to get the query from the user message and post it to the url, example:
.command 4443
bot returns the https://api.gtaliferp.fr:8443/v1/extinction/profiles/main/4443 data and postes it.
And also, i wanted to make the different data on an embed like this: data 1: data data 2: data .... but i cant do it, ( check the url provided for the data titles if you want to help with that)
So you seperated your module from the rest of the command with this line marked below
module.exports = {
//definition
name: "glifestats", //the name of the command
category: "⌨️ Programming", //the category this will be listed at, for the help cmd
aliases: [""], //every parameter can be an alias
cooldown: 4, //this will set it to a 4 second cooldown
usage: "glifestats <id>", //this is for the help command for EACH cmd
description: "check stats", //the description of the command
} //here
Also term is reqesting an option that is not defined
const term = interaction.options.getString('term');
Interaction is not defined
run: async (client, message, args, cmduser, text, prefix) => {
await interaction.deferReply();
const term = interaction.options.getString('term');
Try this
const config = require(`${process.cwd()}/botconfig/config.json`) // is this needed if not, delete
var ee = require(`${process.cwd()}/botconfig/embed.json`) // is this needed if not, delete
const fetch = require("node-fetch");
const {
MessageEmbed
} = require(`discord.js`); // is this needed if not, delete
module.exports = {
name: "glifestats", //the name of the command
category: "⌨️ Programming", //the category this will be listed at, for the help cmd
aliases: [""], //every parameter can be an alias
cooldown: 4, //this will set it to a 4 second cooldown
usage: "glifestats <id>", //this is for the help command for EACH cmd
description: "check stats", //the description of the command
options: [{
name: "term",
description: "Code to search",
required: true,
type: "STRING",
}],
run: async (client, interaction) => {
await interaction.deferReply();
const term = interaction.options.getString('term');
const url = `https://api.gtaliferp.fr:8443/v1/extinction/profiles/main/${term}`
const list = await fetch(url).then(response => response.json())
// Do something with list
console.log(list)
return interaction.followUp({
content: `List has been logged but can't be sent yet because it is an object and need to be further worked to get specific elements from it`
})
// Above seemed cleaner to me
/*
const query = new URLSearchParams({
term
});
const {
list
} = await fetch(`https://api.gtaliferp.fr:8443/v1/extinction/profiles/main/${query}`)
.then(response => response.json());
*/
}
}

interaction.options.getMember is not a function

first time posting here. I hope I've posted this correctly, but basically getting the error message "interaction.options.getMember is not a function" I've tried using getUser as well (someone suggested this) and it doesnt seem to fix the problem. I'm pretty new to all this so please go easy on me. as far as I can see everything has been defined correctly and I'm pretty sure the issue is from here somewhere as the rest of the commands work absolutely fine. Any help greatly appreciated!!
const { Client, CommandInteraction, MessageEmbed } = require("discord.js");
module.exports = {
name: "ban",
description: "Bans the target member",
permission: "ADMINISTRATOR",
options: [
{
name: 'target',
description: "Select a target to ban",
type: "USER",
required: true,
},
{
name: 'reason',
description: "Provide a reason for the ban",
type: "STRING",
required: true,
},
{
name: 'messages',
description: "Choose one of the choices",
type: "STRING",
required: true,
choices: [
{
name: "Don't delete any",
value: "0"
},
{
name: "Previous 7 days",
value: "7"
}
]
},
],
/**
*
* #param {Client} client
* #param {CommandInteraction} interaction
*/
execute(client, interaction) {
//ERROR IS LINE BELOW//
const Target = interaction.options.getMember('target');
if (Target.id === interaction.member.id)
return interaction.followUp({embeds: [new MessageEmbed().setColor("RED").setDescription(`⛔ You can't ban yourself.`)]})
if (Target.permissions.has("ADMINISTRATOR"))
return interaction.followUp({embeds: [new MessageEmbed().setColor("RED").setDescription(`⛔ You can't ban an administrator.`)]})
const Reason = interaction.options.getString('reason');
if (Reason.length > 512)
return interaction.followUp({embeds: [new MessageEmbed().setColor("RED").setDescription(`⛔ The reason cannot exceed 512 characters`)]})
const Amount = interaction.options.getString('messages')
Target.ban({days: Amount, reason: Reason})
interaction.followUp({embeds: [new MessageEmbed().setColor("GREEN").setDescription(`✅ **${Target.user.username}** has been banned!`)]})
}
}
According to your code, and per Discord API, you have your member (actually user) here:
name: 'target',
description: "Select a target to ban",
type: "USER",
required: true,
so that line should read
const Target = interaction.options.getUser('target');
You need to get the member by using the below code
const targetMember = interaction.guild.members.cache.find(member => member.id === Target)
The rest needs to change Target to targetMember or simplify with example below:
if (targetMember.permissions.has(Permissions.FLAGS.BAN_MEMBERS) || targetMember.user.bot || targetMember.user.id === interaction.user.id) {
return interaction.reply({
content: 'You are not authorized to ban this member or yourself.',
ephemeral: true
})
I actually managed to fix the issue before I went sleep at 4am. Essentially the problem was actually caused by the execute (client, interaction). In my other file, these parameters are (interaction, client). I also changed all instances of "followUp" with "reply" and it started working as intended.
Thanks for helping out though!

Adding buttons to an application sent to specified applicationChannelId

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!

Posting Form data as json to nested serializer from ReactJS

I am getting this error {"user":["This field is required."]} in reactjs when posting data to an endpoint which has the following serializer
class ProfileSerializer(serializers.ModelSerializer):
user = UserProfileSerializer()
class Meta:
model = models.Profile
fields = ['user',
'address',
'city',
'country',
'user_type',
'telephone_Number',
'organisation_name',
]
def create(self, validated_data):
print(validated_data)
user_data = validated_data.pop('user')
user = UserProfile.objects.create(**user_data)
profile = Profile.objects.create(user=user, **validated_data)
return profile
On the network tab of the browser i can see all the data is captured as shown
user: [{"name":"Testing user"},{"email":"test#gmail.com"},{"password":"*****"},{"is_active":true}]
user_type: 2
organisation_name: Testing company
address: N/A
city: N/A
country: Test
telephone_Number: 8888763
This is how i am posting the data from reactjs
let data = this.state.data;
let user = [
{ name: data.name },
{ email: data.email },
{ password: data.password },
{ is_active: data.is_active },
];
let form_data = new FormData();
form_data.append("user", JSON.stringify(user));
form_data.append("user_type", data.user_type.value);
form_data.append("organisation_name", data.organisation_name);
form_data.append("address", data.address);
form_data.append("city", data.city);
form_data.append("country", data.country);
form_data.append("telephone_Number", data.telephone_Number);
await saveUser(form_data);
Edits
Upon further checks i am noticing the issue is on this await saveUser(form_data);
The data object on the http post requst is empty as shown data: FormData {} So the issue seems to be how to convert form data to json object. How do i convert this?
Please help what could be wrong with this? Kindly assist
FormData was really causing me lots of problem My problem was the format i was using to post data to the server. I created javascript objects from my state objects and i was able to successfully post data to the server as shown below. I had to give an answer so that if in future someone encounters same issue, s/he doesn't suffer like i did. lol
let data = this.state.data;
let user = {
name: data.name,
email: data.email,
password: data.password,
is_active: data.is_active,
};
const userData = {
user,
organisation_name: data.organisation_name,
name: data.name,
address: data.address,
city: data.city,
country: data.country,
telephone_number: data.telephone_Number,
user_type: data.user_type.value,
};
await saveUser(userData);

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