Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
This is the code I have: https://hastebin.com/loqicunulu.js (too large to post here)
I want it so if I do !warn USER REASON it adds them to a json file, which it does,
then if I do it again !warn USER REASON it will kick them as they've already been warned (line 13) - don't want them to be added the the json file here.
But at the moment it just keeps on adding them to the json file every time I do it, and doesn't kick them.
I think it is completely skipping my if statment.
That's because you're only including modlogs.json one time, at the beginning of execution. After you add the user to the warn list, you're not updating the warn list in memory with the new contents. Instead of including the modlog like that, try just moving your if statement into the fs.readFile callback. That way you have the latest contents of the file to check against.
disclaimer: this code is not tested, but it should give you the direction you need to go in, and might just work out of the box.
const Discord = require('discord.js');
const fs = require('fs');
const path = require('path');
exports.run = (client, message, args) => {
let reason = args.slice(1).join(" "); // joins every argument after the first
let user = message.mentions.users.first(); // grabs the first user mentioned
let modLog = client.channels.find("name", "mod-log"); // find the channel to post to
if (!modLog) return message.reply("No channel named `mod-log` found.").catch(console.error); // sanity check
if (message.mentions.users.size < 1) return message.reply("You must mention someone to warn.").catch(console.error); // sanity check
if (args.length < 2) return message.reply("You must supply a reason.").catch(console.error); // sanity check
fs.readFile(path.join(__dirname, "../moderation") + "/modlogs.json", "utf-8", function(err, data) { // read the JSON file
if (err) throw err; // throw error if applicable
var arrayOfObjects = JSON.parse(data); // parse the data
for (let i = 0; i < arrayOfObjects.warns.length; i++) { // loop through all keys in warns file
if (arrayOfObjects.warns[i].user_id === user.id) {
message.reply("User already warned. Kicking user.");
message.guild.member(user).kick(); // kicks member
return;
}
}
arrayOfObjects.warns.push({ // push the data into the array
user: `${user.username}#${user.discriminator}`,
user_id: `${user.id}`,
mod: `${message.author.username}#${message.author.discriminator}`,
mod_id: `${message.author.id}`,
reason: reason
});
fs.writeFile(path.join(__dirname, "../moderation") + "/modlogs.json", JSON.stringify(arrayOfObjects, null, 2), "utf-8", function(err) {
if (err) throw err;
const embed = new Discord.RichEmbed() // send embed of warning
.setColor(0x00AE86)
.addField("Action:", "Warning")
.addField("User:", `${user.username}#${user.discriminator}\nUserID: ${user.id}`)
.addField("Mod:", `${message.author.username}#${message.author.discriminator}\nUserID: ${message.author.id}`)
return client.channels.get(modLog.id).sendEmbed(embed); // send embed to mod-log channel
});
});
};
exports.conf = {
enabled: true,
guildOnly: false,
aliases: [],
permLevel: 1
};
exports.help = {
name: "warn",
description: "Warns a mentioned user.",
usage: "warn <mention> <reason>"
};
Related
I'm trying to save a value of the server being "Down" or "Up", it seems to be working fine, however, when I clear the console, then run the bot again, it looks to have reset the database fully, is there a way to make the database, work like a normal database would? (Save after restart)
I'm having a check to see if the server is up, then don't allow it to run the command and say it's already online.
I wasn't like this before, and I haven't used quick.db for a while, so sorry if I missed anything.
Code:
// Main requirements
const { ROLE_SSUPIN, CHANNEL_SSU, CHANNEL_ROLESEL, BOT_PREFIX } = require('../../config.json')
const commandName = 'ssu'
// Optional Requirements
const { MessageEmbed } = require('discord.js')
const { QuickDB } = require('quick.db');
const db = new QuickDB();
// Main Code
module.exports = async client => {
client.on('messageCreate', async message => {
if (message.author.bot) return;
if (!message.content.toLowerCase().startsWith(BOT_PREFIX)) return;
const command = message.content.split(' ')
const args = message.content.substring(1).split(' ')
if (command.toString().toLowerCase().replace(BOT_PREFIX, '').startsWith(commandName)) {
const ssuStatus = await db.get("ssu.status")
await db.set("ssu.status", "down");
console.log(ssuStatus)
if (!message.member.roles.cache.get('998320362234323026')) return message.reply("Only staff with `SSU Permissions` can use this command!")//.then(m => {setTimeout( function() { m.delete(), message.delete() }, 10000)});
if (!message.channel.id == CHANNEL_SSU) return message.reply(`Please use this command in <#${CHANNEL_SSU}>.`)
if (ssuStatus == 'up') return message.reply(`Server Status is already set to Online. Say \`${BOT_PREFIX}Server Status Set Offline\` if you believe this is a mistake.`)
message.channel.send(`
Start up done.
`)
.then(await db.set("ssu.status", "up"))
}
})
}
I had "await db.set("ssu.status", "down");" in the start of each function, so it was reseting it back to "Down", I didn't mean for it do that, if you have the same issue, make sure that you don't have anything that sets the database value in the start, as it might be the reason it's getting reset and you think it's wiping.
I'm pretty new to javascript or discord.js but my guess was something like this:
client.on('channelCreate', channel =>
{
message.channel.send('test');
})
I'm guessing 'channelCreate' doesn't exist.
Your guess is right.
According to the discord.js documentation, you can listen to a channelCreate event to trigger something when a channel is created.
To know who created a channel, your bot need to access the audit logs and the first entry of it.
client.on("channelCreate", async (channel) => {
if (!channel.guild) return;
// Fetch the audit logs of CHANNEL_CREATE events.
const audit_logs = await channel.guild.fetchAuditLogs({
limit: 1,
type: "CHANNEL_CREATE"
});
if (!audit_logs.entries.first()) {
console.error("No entry found.");
return;
}
const entry = audit_logs.entries.first();
const executor = entry.executor;
// The executor property is type User,
// so you can easily check if it's a bot by doing...
const is_bot = executor.bot;
// `is_bot` will be boolean.
});
Resources
https://discord.js.org/#/docs/discord.js/13.7.0/class/Guild?scrollTo=fetchAuditLogs
https://discord.js.org/#/docs/discord.js/13.7.0/class/GuildAuditLogsEntry?scrollTo=executor
https://discord.js.org/#/docs/discord.js/13.7.0/class/User?scrollTo=bot
Note: I am using the readline module in this code and the code that isn't working is in a rl.question statement.
I am trying to add an await statement to my fs.writeFileSync but any time I run the program the await function just doesn't work, like the await function isn't even there. It doesn't show any errors in the console and it only writes to the file wanted after the rl.question is closed.
I have tried promisifying the code, and I have tried making a seperate variable for question 2 because i currently have 2 questions in one readline interface.
javascript
rl.question('Type discord invite here: ', async (invite) => {
console.log(`${invite} is a bout to get pooed`);
const invites = {
"inviteCode": `${invite}`
}
const inviteJSON = JSON.stringify(invites)
await fs.writeFileSync("code.json", inviteJSON);
// I want this file to get written before the next question gets asked but it only writes after the second question is asked
r1.question('Type what you want the bot to say (Less than 2000 characters): ', async (mess) => {
const messa = {
"mess": `${mess}`
}
console.log(code.inviteCode) // this is supposed to be the new string that was supposed to be set before the second question but it just outputs as the JSON contents that I manually put in.
const messJSON = JSON.stringify(messa)
await fs.writeFileSync("message.json", messJSON);
console.log("Invite code set.....")
fs.readdir("./bots", (err, botfiles) => {
if(err) console.error(err)
let bots = botfiles.filter(f => f.split(".").pop() === "js");
bots.forEach((f, i) => {
require(`./bots/${f}`);
console.log(`${i + 1} bots loading.`);
});
});
r1.close();
});
});
I expect that the file is written to before the second question but in reality it gets written after the second question is answered.
I am making an RP profile creation setup for a discord bot using javascript. I have the conversation starting in a channel and moving to private messaging with the bot. The first question gets asked and the reply from the user is stored in a database. That is working fine.
What seems to be the problem comes when I try to use another command inside a private message with the bot to move to the next step of the RP profile creation. It doesn't seem to register the command is being used. Can commands even be used in private messaging with a bot?
I used the same code as the first question that worked, changed what needed to be, but nothing that should have broken the code. It just looks to not even see the second command, which is stored in a separate command file. How would I do this?
module.exports.run = async (bot, message, args) => {
message.author.send(` SECOND QUESTION, **What is the age of your Brawler or Character?**`)
.then((newmsg) => { //Now newmsg is the message you send to the bot
newmsg.channel.awaitMessages(response => response.content, {
max: 1,
time: 300000,
errors: ['time'],
}).then((collected) => {
newmsg.channel.send(`Your brawler's age is: **${collected.first().content}**
If you are okay with this age, type !profilegender to continue the profile creation process!
If you would like to edit your age, please type !profileage`)
con.query(`UPDATE profile SET age = '${collected.first().content}' WHERE id = ${message.author.id}`);
console.log("1 record updated!")
}).catch(() => {
newmsg.channel.send('Please submit an age for your character. To restart Profile creation, please type "!profilecreate" command in Profile Creation channel on the server.');
});
});
}
Thanks in advance for your time!
EDIT: This is part of the code that is the bot/client is listening for on message.
bot.on(`message`, async message => {
if(message.author.bot) return;
if(message.channel.type === "dm") return;
con.query(`SELECT * FROM profile WHERE id = '${message.author.id}'`, (err, rows) => {
if(err) throw err;
var sql;
if(rows.length < 1) {
var sql = (`INSERT INTO profile (id, username) VALUES (${message.author.id}, '${message.author.tag}')`);
} else {
var sql = (`UPDATE profile SET username = '${message.author.tag}' WHERE id = ${message.author.id}`);
};
//con.query(sql, console.log);
//if (err) throw err;
//console.log("1 record inserted!");
});
Answer from comments
Inside of your client.on("message") there's an if check that exits the function if the channel is a DMChannel
if(message.channel.type === "dm") return;
To avoid that, simply remove this line: in this way, the bot will execute the command regardless of the channel type. If you want to allow some commands only in certain channels, you can do that either in the client.on("message") or in the function of the command itself.
For a Discord bot I have a command that changes the prefix of that guild, it 'works fine' as in it updates it in my database (MySQL Workbench), but the commands still triggers for ANY prefix, so if you stick any character in-front of the command it triggers instead of the one in the database.
This is my code to check the prefix:
let prefix = "!";
connection.query(`SELECT * FROM guilds WHERE guildid = ${message.guild.id}`, (error, commands) => {
if (error) throw error;
if (commands.length) { //guild exists in database
commands.forEach(value =>
prefix = value.prefix;
console.log(value.prefix); // returns correct prefix from database
});
} else {
prefix = "!";
}
});
It's a little challenging trying to read your code with the arrow short hands. I'm rather sure this is where your error is coming form.
prefix = value.prefix; console.log(value.prefix);
Do you mean to be logging the original value.prefix before reassigning it?
Try this code.
commands.forEach(function(value){
console.log(value.prefix);
prefix = value.prefix;
})
Javascript Docs on .forEach()