So I'm trying to set up a command to view the amount of candy you have using the info stored in the json file. It doesn't seem to be reading the information correctly.
Here is the command file
const fs = require('fs');
const candyAmount = JSON.parse(fs.readFileSync('./candyheld.json', {encoding:'utf8'}));
const { prefix } = require('../../config.json');
module.exports = {
name: 'candy',
description: 'Displays the amount of candy the user has.',
execute (message, args) {
if (!candyAmount[message.author.id]) return message.channel.send(`You haven\'t started the event yet! Type ${prefix}trickortreat to start!`);
const { candyStored } = candyAmount[message.author.id].candyStored;
message.channel.send(`You have ${candyStored} pieces of candy!`);
},
};
and here is what the json file looks like when it has the info
{"ID":{"candyStored":5}}
I have removed the actual ID number and replaced it with just the word just for this moment. The actual number is in the code.
trickortreat command file
const fs = require('fs');
const candyAmount = JSON.parse(fs.readFileSync('./candyheld.json', {encoding:'utf8'}));
module.exports = {
name: 'trickortreat',
description: 'Special Halloween command',
execute(message, args) {
if (!candyAmount[message.author.id]) {
candyAmount[message.author.id] = {
candyStored: 5
}
fs.writeFile('./candyheld.json', JSON.stringify(candyAmount), err => {
if (err) console.error(err);
});
return message.channel.send('For starting the event, you have been given 5 pieces of candy!');
}
// Stores a random number of candy from 1-3
let candy = Math.floor(Math.random() * 3 + 1);
// Sets the possible messages to be received
let trickortreatmessage = [
'The scarecrow standing behind you jumps out at you and makes you drop all your candy!',
`${message.guild.members.cache.random()} was nice enough to give you Candy! You got ${candy} pieces of candy!`,
`Oh no you asked ${message.guild.members.cache.random()} for Candy and they decided to egg you instead!`
]
// Store one of the random messages
const trickortreat = trickortreatmessage[Math.floor(Math.random() * trickortreatmessage.length)];
if (trickortreat == trickortreatmessage[0]) {
candyAmount[message.author.id].candyStored = 0;
} else if (trickortreat == trickortreatmessage[1]) {
candyAmount[message.author.id].candyStored = candyAmount[message.author.id].candyStored + candy;
}
fs.writeFile('./candyheld.json', JSON.stringify(candyAmount), err => {
if (err) console.error(err);
});
message.channel.send(trickortreat);
},
};
I've been adding some new things and trying to fix this issue and I got an update that will hopefully help figure this out. I made an "addcandy" command to add candy to specific users mentioned. When I use the command, and then use /candy, it reads it perfectly.
So I'm thinking #ericgio was right in that it has something to do with the "trickortreat" command. It adds the number fine but for some reason "candy" isn't reading that change. But it reads the change when I use "addcandy"
So I managed to figure out for anyone else having the same issue. I changed the "const candyAmount" to just be "require('../../candyheld.json') and did the same for my other files and it seems to read correctly now
old code line
const candyAmount = JSON.parse(fs.readFileSync('./candyheld.json', {encoding:'utf8'}));
new code line
const candyAmount = require('../../candyheld.json');
Related
I am trying to build a discord bot, that would do leveling and warns and such, but i have no idea how I would link a file to the main javascript file so i can have all the database code be "external". I want to use SQLite for my database.
This is currently what i have
client.on("ready", () => {
// Check if the table "points" exists.
const table = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'scores';").get();
if (!table['count(*)']) {
// If the table isn't there, create it and setup the database correctly.
sql.prepare("CREATE TABLE scores (id TEXT PRIMARY KEY, user TEXT, guild TEXT, points INTEGER, level INTEGER);").run();
// Ensure that the "id" row is always unique and indexed.
sql.prepare("CREATE UNIQUE INDEX idx_scores_id ON scores (id);").run();
sql.pragma("synchronous = 1");
sql.pragma("journal_mode = wal");
}
// And then we have two prepared statements to get and set the score data.
client.getScore = sql.prepare("SELECT * FROM scores WHERE user = ? AND guild = ?");
client.setScore = sql.prepare("INSERT OR REPLACE INTO scores (id, user, guild, points, level) VALUES (#id, #user, #guild, #points, #level);");
});
client.on("messageCreate", message => {
if (message.author.bot) return;
let score;
if (message.guild) {
score = client.getScore.get(message.author.id, message.guild.id);
if (!score) {
score = { id: `${message.guild.id}-${message.author.id}`, user: message.author.id, guild: message.guild.id, points: 0, level: 1 }
}
score.points++;
const curLevel = Math.floor(0.1 * Math.sqrt(score.points));
if (score.level < curLevel) {
score.level++;
message.reply(`You've leveled up to level **${curLevel}**! Ain't that dandy?`);
}
client.setScore.run(score);
}
if (message.content.indexOf(config.prefix) !== 0) return;
const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (command === "give") {
// Limited to guild owner - adjust to your own preference!
if (!message.author.id === message.guild.ownerId) return message.reply("You're not the boss of me, you can't do that!");
const user = message.mentions.users.first() || client.users.cache.get(args[0]);
if (!user) return message.reply("You must mention someone or give their ID!");
const pointsToAdd = parseInt(args[1], 10);
if (!pointsToAdd) return message.reply("You didn't tell me how many points to give...");
// Get their current points.
let userScore = client.getScore.get(user.id, message.guild.id);
// It's possible to give points to a user we haven't seen, so we need to initiate defaults here too!
if (!userScore) {
userScore = { id: `${message.guild.id}-${user.id}`, user: user.id, guild: message.guild.id, points: 0, level: 1 }
}
userScore.points += pointsToAdd;
// We also want to update their level (but we won't notify them if it changes)
let userLevel = Math.floor(0.1 * Math.sqrt(score.points));
userScore.level = userLevel;
// And we save it!
client.setScore.run(userScore);
return message.channel.send(`${user.tag} has received ${pointsToAdd} points and now stands at ${userScore.points} points.`);
}
if (command === "leaderboard") {
/*const top10 = sql.prepare("SELECT * FROM scores WHERE guild = ? ORDER BY points DESC LIMIT 10;").all(message.guild.id);*/
// Now shake it and show it! (as a nice embed, too!)
const embed = new EmbedBuilder()
.setTitle("Leader board")
.setDescription("Our top 10 points leaders!")
.setColor("#ff0000")
.addFields({ name: '\u200b', value: '\u200b' });
/*for (const data of top10) {
embed.addFields({ name: client.users.cache.get(data.user).tag, value: `${data.points} points (level ${data.level})` });
}*/
return message.channel.send({ embed: embed });
}
// Command-specific code here!
});
The Idea is that when someone messages in chat, the bot will see that message and randomize the amount of XP given to a member. I dont have a full idea on how this can be done externally, if it can.
If i understand this correctly, you want another JS file to be run inside of your current file. Node JS makes this pretty easy!
require('./filename.js')
(also, you might want to use external files to store your commands too!)
The command I set up just grabs a random user to spice up the message a bit. I had to fix something last night and when I restarted the bot, it is now only getting anyone that has messaged. Before, it was getting any random person in the server like it's supposed to. I have also tried to use
message.guild.members.cache.random();
with the same results. Here is the rest of the code from that command
const Discord = require('discord.js');
const fs = require('fs');
const colors = require('../../colors.json');
const candyAmount = require('../../candyheld.json');
const client = new Discord.Client();
module.exports = {
name: 'trickortreat',
description: 'Special Halloween command',
execute(message, args) {
if (!candyAmount[message.author.id]) {
candyAmount[message.author.id] = {
candyStored: 5
}
fs.writeFile('./candyheld.json', JSON.stringify(candyAmount), err => {
if (err) console.error(err);
});
message.delete();
return message.channel.send('For starting the event, you have been given 5 pieces of candy!');
}
// Stores a random number of candy from 1-3
let candyGiven = Math.floor(Math.random() * 3 + 1);
let jackpot = Math.floor(Math.random() * 10 + 20 );
let highJackpot = Math.floor(Math.random() * 100 + 200);
let randomMember = message.client.users.cache.random();
// Sets the possible messages to be received
let trickortreatmessage = [
'The scarecrow standing behind you jumps out at you and makes you drop all your candy!',
`${randomMember} was nice enough to give you Candy! ${message.author} got ${candyGiven} pieces of candy!`,
`Oh no! ${message.author} asked ${randomMember} for Candy and they decided to egg you instead!`,
`The Headless Horseman rides and slashes his way to every bin of candy all just to give you everything he got!\n\n${message.author} got ${jackpot} Candy!`,
`The wolves howl in sync as Candy rains from the sky! The adrenaline makes you move at lightning speed to grab every piece of Candy!\n\n ${message.author} got ${highJackpot} Candy!!!`
]
// Store one of the random messages
let trickortreat;
let odds = Math.floor(Math.random() * 5000);
if (odds <= 25) trickortreat = trickortreatmessage[4]; // .5% chance
else if (odds <= 49) trickortreat = trickortreatmessage[0]; // .5% chance
else if (odds <= 499) trickortreat = trickortreatmessage[3]; // 9% chance
else if (odds <= 1999) trickortreat = trickortreatmessage[2]; // 30% chance
else trickortreat = trickortreatmessage[1]; // 60% chance
if (trickortreat == trickortreatmessage[0]) {
candyAmount[message.author.id].candyStored = 0;
} else if (trickortreat == trickortreatmessage[1]) {
candyAmount[message.author.id].candyStored += candyGiven;
} else if (trickortreat == trickortreatmessage[3]) {
candyAmount[message.author.id].candyStored += jackpot;
} else if (trickortreat == trickortreatmessage[4]) {
candyAmount[message.author.id].candyStored += highJackpot;
}
fs.writeFile('./candyheld.json', JSON.stringify(candyAmount), err => {
if (err) console.error(err);
});
const embed = new Discord.MessageEmbed()
.setColor(colors.serverRed)
.addField('\u200B', `**${trickortreat}**`)
message.delete();
message.channel.send(embed);
},
};
I had the same problem that "message.guild.members.cache" starts empty even though I hadn't done any code changes related to it. It was due to changes made by Discord.
It is easy to fix though. You need to log in to the Discord developer site > Applications, choose your application/bot, got to the "Bot" tab, scroll down to "Privileged Gateway Intents" and tick off the "PRESENCE INTENT" and "SERVER MEMBERS INTENT
":
Note that if your bot is in 100 or more servers you need to whitelist it.
After that I restarted the bot and now it works fine again.
Now, I have my shop and all the items already. I want the user so when they buy the FishingRod, they get put in a new Set();, and once they are in that set they can use the fish command. Here's my code for the 'buy' command:
else if (command === 'buy') {
const args = message.content.slice(PREFIX.length).trim().split(' ');
if (isDead.has(message.author.id)) {
message.channel.send('You\'re dead right now lmao you need to wait 5 more minutes before using any more currency and game related commands');
}
const item = await CurrencyShop.findOne({ where: { name: { [Op.like]: commandArgs } } });
if (!item) return message.channel.send('That item doesn\'t exist.');
if (args === 'FishingRod') {
hasRod.add(message.author.id);
}
if (item.cost > currency.getBalance(message.author.id)) {
return message.channel.send(`You don't have enough currency, ${message.author}`);
}
const user = await Users.findOne({ where: { user_id: message.author.id } });
currency.add(message.author.id, -item.cost);
await user.addItem(item);
message.channel.send(`You've bought a ${item.name}`);
}
As you can see, I've already made it so when the args are 'FishingRod', it puts them in the Set. The problem is that when this happens, and I try running the fish command, it still says I haven't got a FishingRod and need to buy one. Any help would be appreciated.
Okay, you're trying to compare the command arguments (which is an array) to a string. You could just do args[0] to get the first argument. Also, you're making it so that it has to be "FishingRod" and can't be lowercase. Try args[0].toLowerCase() === "fishingrod".
I'm using the backpack.tf API for a Discord bot. I'm currently attempting to make a price command, using the API to find the prices of the items. Rather than returning the current price, the API returns all of the price updates, as shown below.
Only the last value in this call (85) is currently correct and updated. The code I'm using to send and log the results is as follows:
const Discord = require("discord.js");
const superagent = require("superagent");
String.prototype.toProperCase = function() {
return this.replace(/\w\S*/g, function(txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); });
};
module.exports = {
run: async(client, message, args) => {
let item = args[0]
let quality = args[1]
let { body } = superagent
.get(`https://backpack.tf/api/IGetPriceHistory/v1?appid=440&item=${item}&quality=${quality}&tradable=Tradable&craftable=Craftable&priceindex=0&key=5eeea0c9c995374dc219a4e2`);
message.channel.send(new Discord.MessageEmbed()
.setTitle(`Price info of ${item.toProperCase()} (${quality.toProperCase()})`)
.setDescription(`${response.history[HIGHESTNUMBER].value} refined metal`)
)
},
aliases: ["price", "gp"]
}
Where HIGHESTNUMBER is shown in the code is where I need the highest number from the returned JSON. If and how am I able to complete this? Thanks.
const Discord = require("discord.js"),
bot = new Discord.Client();
let pre = "?"
bot.on("message", async msg => {
var msgArray = msg.content.split(" ");
var args = msgArray.slice(1);
var prisonerRole = msg.guild.roles.find("name", "Prisoner");
let command = msgArray[0];
if (command == `${pre}roll`) {
if (!msg.member.roles.has(prisonerRole.id)) {
roll = Math.floor(Math.random()*6)+1;
msg.reply(`You rolled a ${roll}`)
} else {
msg.reply(`HaHa NOOB, you're in prison you don't get priveleges!`)
}
}
if (command == `${pre}kick`) {
var leaderRole = msg.guild.roles.find("name", "LEADER");
var co_leaderRole = msg.guild.roles.find("name", "CO-LEADER");
if (msg.member.roles.has(leaderRole.id) ||
msg.member.roles.has(co_leaderRole.id)) {
var kickUser = msg.guild.member(msg.mentions.users.first());
var kickReason = args.join(" ").slice(22);
msg.guild.member(kickUser).kick();
msg.channel.send(`${msg.author} has kicked ${kickUser}\nReason: ${kickReason}`);
} else {
return msg.reply("Ya pleb, you can't kick people!");
}
}
})
bot.login("token").then(function() {
console.log('Good!')
}, function(err) {
console.log('Still good, as long as the process now exits.')
bot.destroy()
})
Everything works except actually kicking the person. The message sends nut it doesn't kick people. For example, when I type in ?kick #BobNuggets#4576 inactive, it says
#rishabhase has kicked #BobNuggets
Reason: inactive
But it doesn't actually kick the user, which is weird, can you help me?
Change
msg.guild.member(kickUser).kick();
to
kickUser.kick();
also, make sure the bot is elevated in hierarchy
Use kickUser.kick();
I recommend using a command handler to neaten up your code. You don't want all your commands in one .js file.
Try something like this for the Ban command itself. I use this for my Bot:
client.on("message", (message) => {
if (message.content.startsWith("!ban")) {
if(!message.member.roles.find("name", "Role that can use this bot"))
return;
// Easy way to get member object though mentions.
var member= message.mentions.members.first();
// ban
member.ban().then((member) => {
// Successmessage
message.channel.send(":wave: " + member.displayName + " has been successfully banned :point_right: ");
}).catch(() => {
// Failmessage
message.channel.send("Access Denied");
});
}
});
That should work, set the role you want to use it (cAsE sEnSiTiVe) and change !ban to whatever you feel like using. If you change all "ban"s in this to kick, it will have the same effect. If this helped you, mark this as the answer so others can find it, if not, keep looking :)