discord.js v12 - Warn command for each guild - javascript

I have script for warn command and i need help with that, because this
code working, this command saving warns in warnings.json, but when i warn someone that warn be in every guild i want only in one guild warns. Please help :D
const { MessageEmbed } = require("discord.js")
const fs = require('fs')
const warns = JSON.parse(fs.readFileSync("./warnings.json", "utf8"))
const moment = require('moment')
module.exports = {
name: "warn",
description: "Wysyła ankiete",
guildOnly: true,
cooldown: 5,
run(msg, args) {
// Embed na permisjebota
const permisjebota = new MessageEmbed()
.setTitle("⛔ Nie mam uprawnień! :O")
.setColor('ffff00')
.setDescription("Nie mam uprawnień do tej komendy! Daj mi uprawnienia lub skonsultuj się z adminem serwera")
.setTimestamp()
// Embed na permisje dla użytkownika
const permisje = new MessageEmbed()
.setTitle("Nie masz permisji do tej komendy! :O")
.setColor('ffff00')
.setDescription("Nie masz uprawnień do tej komendy! Jeżeli uważasz, że to błąd skonsultuj się z adminem serwera!")
if (!msg.member.guild.me.hasPermission("ADMINISTRATOR"))
return msg.channel.send(permisjebota)
if (!msg.member.hasPermission("MANAGE_MESSAGES")) return msg.channel.send(permisje)
if(!args[0, 1]) {
const bananekbot = new MessageEmbed()
.setTitle("Nie podałeś argumentów!")
.setColor('ffff00')
.setDescription("Poprawne użycie: `m!warn <nick> <powód>`")
return msg.channel.send(bananekbot)
}
var warnUser = msg.guild.member(msg.mentions.users.first() || msg.guild.members.get(args[0]))
var reason = args.slice(1).join(" ")
if (!warnUser) return msg.channel.send("Brak argumentu poprawne użycie: m!warn <nick> <powód>")
if (!warns[warnUser.id]) warns[warnUser.id] = {
warns: 0,
}
warns[warnUser.id].warns++
fs.writeFile("./warnings.json", JSON.stringify(warns), (err) =>{
if(err) console.log(err)
})
const warnembed = new MessageEmbed()
.setTitle("✅ Nadano warna")
.setColor('ffff00')
.setTimestamp()
.setDescription(`Użytkownik: ${warnUser} (${warnUser.id})
Nadający warna: ${msg.author}
Powód: ${reason}`)
return msg.channel.send(warnembed)
}
}

A potential solution to this is to have warnings.json as an array, and in side containing an object with guild id, warns and anything else you need to store. So warnings.json ends up something like this.
[
{
"guild_id": "12345678901234",
"an_extra": "Thing",
"warns": [
"your_warns",
"are_here",
"store_in_any_format"
]
},
{
"guild_id": "12345678901234",
"an_extra": "Guild",
"warns": [
"so_on",
"And so forth",
"go the warns and guilds"
]
}
]
This way, you can simply do Array.find(guild => guild.guild_id === msg.guild.id) (Assuming the guild you are trying to access is msg.guild).
Learn more on MDN about Array.prototype.find()

Related

Cannot read properties of undefined (reading 'send') (Discord.js v13)

i have been trying to make a leaveserver code for my bot, but i always get the error message Cannot read properties of undefined (reading 'send') I really wanna know why it always says the error messages! Please help me! Thanks!
const Discord = require("discord.js")
const rgx = /^(?:<#!?)?(\d+)>?$/;
var self = this
const OWNER_ID = require("../../config.json").OWNER_ID;
module.exports = {
name: "leaveserver",
description: "leavs a server",
run: async (client, message, args) => {
if (!OWNER_ID)
return message.channel.send("This command is Owner Only")},
async run(message, args) {
const guildId = args[0];
if (!rgx.test(guildId))
return message.channel.send("Please Provide a valid server id!")
const guild = message.client.guild.cache.get(guildId);
if (!guild) return message.channel.send(message, 0, 'Unable to find server, please check the provided ID');
await guild.leave();
const embed = new MessageEmbed()
.setTitle('Leave Guild')
.setDescription(`I have successfully left **${guild.name}**.`)
.setFooter(message.member.displayName, message.author.displayAvatarURL({ dynamic: true }))
.setTimestamp()
.setColor(message.guild.me.displayHexColor);
message.channel.send({embeds: [embed]});
}
}
Try this code
const {
MessageEmbed
} = require("discord.js")
const rgx = /^(?:<#!?)?(\d+)>?$/;
const OWNER_ID = require("../../config.json").OWNER_ID;
module.exports = {
name: "leaveserver",
description: "leaves a server",
run: async (client, message, args) => {
const guildId = args[0];
const guild = message.client.guilds.cache.get(guildId);
if (!OWNER_ID) return message.channel.send("This command is Owner Only");
if (!rgx.test(guildId)) return message.channel.send("Please Provide a valid server id!")
if (!guild) return message.channel.send(message, 0, 'Unable to find server, please check the provided ID');
await guild.leave();
const embed = new MessageEmbed()
.setTitle('Leave Guild')
.setDescription(`I have successfully left **${guild.name}**.`)
.setFooter({
text: message.member.displayName,
iconURL: message.author.displayAvatarURL({
dynamic: true
})
})
.setTimestamp()
.setColor(message.guild.me.displayHexColor)
message.channel.send({
embeds: [embed]
})
}
}
Removed the duplicated async run(message, args) {
Try to do this:
const client = new Discord.Client({intents:
["GUILDS", "GUILD_MESSAGES"]});
client.on("message" , msg => {
await guild.leave();
const embed = new MessageEmbed()
.setTitle('Leave Guild')
.setDescription(`I have successfully left **${guild.name}**.`)
.setFooter(msg.member.displayName, msg.author.displayAvatarURL({ dynamic: true }))
.setTimestamp()
.setColor(msg.guild.me.displayHexColor);
msg.channel.send({embeds: [embed]});
})

Discord.JS bot not replying to commands nor returning a error in console regarding it

I've been struggling to get my new Discord bot's command handler to work, While it is seeing the command files (as indicated by its log entry on startup stating the amount of commands it has loaded) it either isn't sending the messages, or it isn't even executing them.
Here's my code:
const { Client, Intents, Collection } = require('discord.js');
const { token, ownerid, statuses, embedColors, prefix } = require('./cfg/config.json');
const client = new Client({ intents: [Intents.FLAGS.GUILDS] });
const fs = require('fs');
const { config } = require('process');
client.commands = new Collection();
const commands = [];
const cmdfiles = fs.readdirSync('./cmds').filter(file => file.endsWith('.js'));
client.once('ready', () => {
console.clear
console.log(`Ready to go, Found ${cmdfiles.length} commands and ${statuses.length} statuses!`)
setInterval(() => {
var status = Math.floor(Math.random() * (statuses.length -1) +1)
client.user.setActivity(statuses[status]);
}, 20000)
}),
client.on("error", (e) => console.log(error(e)));
client.on("warn", (e) => console.log(warn(e)));
// Command Handler
for (const file of cmdfiles) {
const command = require(`./cmds/${file}`);
commands.push(command.data);
}
client.on('messageCreate', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
if (!client.commands.has(command)) {
embeds: [{
title: ":x: Oopsie!",
color: config.embedColors.red,
description: `Command ${args.[0]} doesn't exist! Run ${config.prefix}help to see the avaliable commands!`,
footer: app.config.footer + " Something went wrong! :("
}];
} else {
try {
client.commands.get(command).execute(message, args);
} catch (error) {
console.error(error);
embeds: [{
title: ":x: Oopsie!",
description: "Command execution failed",
fields: [
{ name: "Error Message", value: `${e.message}` }
],
footer: app.config.footer + " Something went wrong :("
}];
}
message.channel.send
}});
client.login(token);
and the test command is
module.exports = {
name: "test",
description: "does as it implies, dingusA",
async execute(client, message, args) {
message.channel.send("This is a message!");
}
}
You need the GUILD_MESSAGES intent in order to receive messages in guilds.
Add the following intent in your code
const client = new Client({ intents: [
Intents.FLAGS.GUILDS,
Intents.FLAGS.GUILD_MESSAGES ]
})
This applies to other things as well eg. DIRECT_MESSAGES for DMs and etc.

Pick a random picture from a directory

This is my current code:
const superagent = require("snekfetch");
const Discord = require('discord.js')
const random = require('random')
const os = require('os')
module.exports.run = async (client, message, args) => {
if (!message.channel.nsfw) {
message.react('💢');
return message.channel.send({embed: {
color: 16734039,
description: "CO TY ROBISZ! TE ZDJENCIA SA TYLKO DLA DOROSLYCH! (idz na kanal NSFW)"
}})
}
superagent.get('https://nekos.life/api/v2/img/ero')
.end((err, response) => {
const embed = new Discord.RichEmbed()
.setTitle(":smirk: Eevee")
.setImage(random.choice(os.listdir("./app/eevee")))
.setColor(`RANDOM`)
.setFooter(`Tags: eevee`)
.setURL(response.body.url);
message.channel.send(embed);
}).catch((err) => message.channel.send({embed: {
color: 16734039,
description: "Something is wrong... :cry:"
}}));
}
module.exports.help = {
name: "eevee",
description: "Fajno zdjencia",
usage: "eevee",
type: "NSFW"
}
When I try to run it, I get this error message:
TypeError: os.listdir is not a function
Is there anything I can do to fix this problem?
I don't really know the os package but after a bit of researching I've found no readdir function. If you want to get all files of a directory you also can do it like this:
const fs = require('fs')
const allMyFiles = fs.readdirSync();
Also you are creating your embed with RichEmbed() which is outdated. Since v12 you have to use MessageEmbed():
const exampleEmbed = new Discord.MessageEmbed()
.setTitle('Test')
[...]

Problem with sending text from yaml Discord.js

i have a problem sending text from yaml. Saving text works but sending does not. Here's the code:
const { Message, MessageEmbed } = require("discord.js")
const { channel } = require('./kanal')
const db = require('quick.db')
module.exports = {
name: "reklama",
guildOnly: true,
description:
"Change guild prefix. If no arguments are passed it will display actuall guild prefix.",
usage: "[prefix]",
run(msg, args, guild) {
if (!guild) {
const guld = new MessageEmbed()
.setTitle("Błąd!")
.setColor("RED")
.setDescription("Tą komende można tylko wykonać na serwerze!")
.setThumbnail('https://emoji.gg/assets/emoji/3485-cancel.gif')
.setTimestamp()
.setFooter(`${msg.author.tag} (${msg.author.id})`, `${msg.author.displayAvatarURL({dynamic: true})}`)
msg.channel.send(guild)
}
const { settings } = client
const prefixArg = args[0]
if (!settings.get(guild.id)) {
settings.set(guild.id, { prefix: null })
}
if (!prefixArg) {
let Reklama = client.settings.get(guild.id).Reklama
let Kanal = client.settings.get(guild.id).Kanał
const embed = new MessageEmbed()
.setTitle(`Informacje o serwerze: ${msg.guild.name}`)
.addField("Treść reklamy:", Reklama)
.addField("Kanał do wysyłania reklam:", Kanal)
msg.channel.send(embed)
}
setInterval(() => {
Kanal.send(`${Reklama}`)
}, 1000)
},catch(e){
console.log(e)
}
}
Here is a part of command handler:
const args = msg.content.slice(length).trim().split(" ")
const cmdName = args.shift().toLowerCase()
const cmd =
client.commands.get(cmdName) ||
client.commands.find(
(cmd) => cmd.aliases && cmd.aliases.includes(cmdName),
)
try {
cmd.run(msg, args)
} catch (error) {
console.error(error)
}
})
}
The problem is that when I start the bot, it shows me such an error:
let Reklama = client.settings.get(guild.id).Reklama
^
TypeError: Cannot read property 'id' of undefined
The problem is you don't pass the guild variable to your run method. You call cmd.run(msg, args) but run accepts three parameters.
You can either pass the guild or get it from the msg like this:
module.exports = {
name: 'reklama',
guildOnly: true,
description:
'Change guild prefix. If no arguments are passed it will display actuall guild prefix.',
usage: '[prefix]',
run(msg, args) {
// destructure the guild the message was sent in
const { guild } = msg;
if (!guild) {
const embed = new MessageEmbed()
.setTitle('Błąd!')
.setColor('RED')
.setDescription('Tą komende można tylko wykonać na serwerze!')
.setThumbnail('https://emoji.gg/assets/emoji/3485-cancel.gif')
.setTimestamp()
.setFooter(
`${msg.author.tag} (${msg.author.id})`,
`${msg.author.displayAvatarURL({ dynamic: true })}`,
);
return msg.channel.send(embed);
}
const { settings } = client;
const prefixArg = args[0];
if (!settings.get(guild.id)) {
settings.set(guild.id, { prefix: null });
}
if (!prefixArg) {
let Reklama = client.settings.get(guild.id).Reklama;
let Kanal = client.settings.get(guild.id).Kanał;
const embed = new MessageEmbed()
.setTitle(`Informacje o serwerze: ${msg.guild.name}`)
.addField('Treść reklamy:', Reklama)
.addField('Kanał do wysyłania reklam:', Kanal);
msg.channel.send(embed);
}
setInterval(() => {
Kanal.send(`${Reklama}`);
}, 1000);
},
catch(e) {
console.log(e);
},
};

Writing JSON File with Discord.js

Im trying to develop a little warn system for my Discord Bot. If someone types !warn #mention Reason, it should store the data in a JSON File. It works, but only with one User in one Guild. What I want is, that
the JSON File looks like this:
{
"superniceguildid":
{
"member": "636302212787601408",
"warns": 3
},
{
"meber": "7837439745387549"
"warns": 1
}
}
Now only this exists:
{
"627818561947041816": {
"guild": "636302212787601408",
"warns": 3
},
}
How can I do it, that the File is generating like above?
My current code is this:
module.exports = {
name: 'warn',
description: "test",
execute(message, args){
const { Client, MessageEmbed } = require("discord.js")
const client = new Client()
const fs = require("fs")
const ms = require("ms")
warns = JSON.parse(fs.readFileSync("./warns.json", "utf8"))
client.servers = require ("./servers.json")
let guild = client.servers[message.guild.id].message
/*Embeds*/
const oops = new MessageEmbed()
.setTitle("Error")
.setColor("RED")
.setDescription("You cant warn a member. Please ask a Moderator")
.setAuthor("MemeBot", "this is a link")
const Mod = new MessageEmbed()
.setTitle("Error")
.setColor("RED")
.setDescription("You cant warn a Moderator.")
.setAuthor("MemeBot", "linkhere xD")
/**Commands */
let wUser = message.mentions.users.first() || message.guild.members.cache.fetch(`${args[0]}`)
if (!wUser) return message.channel.send("Are you sure, that this was a User? I think it wasn't one...")
let wReason = args.join(" ").slice(27)
if (!wReason) return message.channel.send("Please tell me, why you want to warn this person. Because, you know, it's a warn :D");
if(!message.member.hasPermission("KICK_MEMBERS")) return message.channel.send(oops)
if(wUser.hasPermission("KICK_MEMBERS")) return message.channel.send(Mod)
if(!warns[message.guild.id]) warns[message.guild.id] = {
user: wUser.id,
warns: 0
}
warns[wUser.id].warns++
fs.writeFile("./warns.json", JSON.stringify(warns, null, 4), err => {
if(err) console.log(err)
});
let warnEmbed = new MessageEmbed()
.setTitle("Warned")
.setColor("YELLOW")
.addField("Warned User", `${wUser}`)
.addField("Moderator", `${message.author.id}`)
.addField("Reason", `${wReason}`)
.addField("Number of Warnings", warns[wUser.id].warns)
.addField("Warned at", `${message.createdAt}`)
let warnonEmbed = new MessageEmbed()
.setTitle("Warned")
.setColor("YELLOW")
.addField("Warned on", `${message.guild.name}`)
.addField("Moderator", `${message.author}`)
.addField("Reason", `${wReason}`)
.addField("Warned at", `${message.createdAt}`)
let logchannel = message.guild.channels.cache.find(c => c.id === 'id');
if(!logchannel) return
wUser.send(warnonEmbed)
logchannel.send(warnEmbed)
}
}
That particular layout doesn't make a lot of hierarchical sense. You might want to nest the user inside the guild and any parameters belonging to the user inside that. Something like this...
"superniceguildid":
{
"636302212787601408":
{
"warns": 3
},
"7837439745387549":
{
"warns": 1
}
},
Accessing it then would be as easy as using something like the following:
let guildWarns = warns["superniceguildid"];
let userWarns = guildWarns["636302212787601408"];
let numberOfWarns = userWarns.warns;
you can combine that as well.
let numberOfWarns = warns["superniceguildid"]["636302212787601408"].warns;
Of course, remember that if it doesn't exist it will be undefined.

Categories