How Would I Make an External Database File? - Discord.JS - javascript

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!)

Related

Rate limit on guild.roles.create?

My project involves checking a json with course data and creating roles for each course. This worked fine the first few times but after making a few errors, deleting and recreating, the roles aren't being created.
Update roles command:
Essentially the roles get fetched once so multiple fetch requests aren't needed.
const guild = interaction.guild;
await guild.roles.fetch();
const rolesAdded = Array.from(guild.roles.cache.values()).map((r) => { return r.name; });
for(const d of getDisciplines()){
const roles = getDiscplineRoles(d);
for(const r of roles){
if(rolesAdded.includes(r[0])) continue;
let colour;
if(r[1] == "M"){
colour = "Purple";
} else if (r[1] == "S"){
colour = "Blue";
}
addRole(guild, r[0], colour);
rolesAdded.push(r[0]);
}
let courses = getCourses(d);
courses = courses.map((c) => {
return c[0];
});
for(const course of courses){
if(rolesAdded.includes(course)) continue;
addRole(interaction.guild, course, "LightGrey");
rolesAdded.push(course);
}
}
await interaction.reply("Roles created");
addRole function:
The console.log runs fine so i know this works
addRole: async function(guild, roleName, colour) {
// Get role and create if it doesn't exist
const role = await guild.roles.cache.find((r) => r.name === roleName);
if (role !== undefined){
return;
}
console.log(`${roleName} does not exists`);
await guild.roles.create({
name: roleName,
color: colour,
});
}
I have tried looking up something about a limit but have only found 2 forum posts mentioning 2 numbers, 250 and 1000.
Note: No error is returned at all, the program just seems to be waiting for the request to be filled
Links:
https://github.com/discord/discord-api-docs/issues/1480
https://support.discord.com/hc/en-us/community/posts/360050533812-Extreme-rate-limits-on-the-role-create-endpoint

Discord.JS 13 slash command display a targets users specific user role in and embed,

I am trying to make a slash command that displays a users specific roles when the command is issued.
run: async (client, interaction) => {
try{
const { member, channelId, guildId, applicationId,
commandName, deferred, replied, ephemeral,
options, id, createdTimestamp , roles, cache
} = interaction;
const { guild } = member;
let UserOption = options.getUser("which_user");
if(!UserOption) UserOption = member.user;
try{
await guild.members.fetch();
const member = guild.members.cache.get(UserOption.id);
const roles = member.roles;
const userFlags = UserOption.flags.toArray();
const activity = UserOption.presence?.activities[0];
//create the EMBED
const embeduserinfo = new MessageEmbed()
embeduserinfo.setThumbnail(member.user.displayAvatarURL({ dynamic: true, size: 512 }))
embeduserinfo.setAuthor("Information about: " + member.user.username + "#" + member.user.discriminator, member.user.displayAvatarURL({ dynamic: true }), "https://discord.gg/FQGXbypRf8")
embeduserinfo.addField('**❱ Username:**',`<#${member.user.id}>\n\`${member.user.tag}\``,true)
//embeduserinfo.addField('**❱ ID:**',`\`${member.id}\``,true)
embeduserinfo.addField('**❱ Avatar:**',`[\`Link to avatar\`](${member.user.displayAvatarURL({ format: "png" })})`,true)
embeduserinfo.addField('**❱ Joined Discord:**', "\`"+moment(member.user.createdTimestamp).format("DD/MM/YYYY") + "\`\n" + "`"+ moment(member.user.createdTimestamp).format("hh:mm:ss") + "\`",true)
embeduserinfo.addField('**❱ Joined MetroVan:**', "\`"+moment(member.joinedTimestamp).format("DD/MM/YYYY") + "\`\n" + "`"+ moment(member.joinedTimestamp).format("hh:mm:ss")+ "\`",true)
//embeduserinfo.addField(`❱ [${roles.cache.size}] Roles: `, roles.cache.size < 25 ? Array.from(roles.cache.values()).sort((a, b) => b.rawPosition - a.rawPosition).map(role => `<#&${role.id}>`).join(', ') : roles.cache.size > 25 ? trimArray(roles.cache) : 'None')
if (roles.cache.find(r => r.id === "893330818624282656"))
{
embeduserinfo.addField("test")
}
embeduserinfo.setColor(ee.color)
embeduserinfo.setFooter(ee.footertext, ee.footericon)
//send the EMBED
interaction.reply({embeds: [embeduserinfo], ephemeral: false})
}catch (e){
console.log(e)
}
} catch (e) {
console.log(String(e.stack).bgRed)
}
}
}
if targeted member has role 893330818624282656 display this embed.addField
if (roles.cache.find(r => r.id === "893330818624282656"))
{
embeduserinfo.addField("test")
}
Step by step goal
User 1 uses slash command to view users 2 profile
User 1 executes slash command /profile #user2
An embedd is sent to the channel the command is executed in with ephemeral: true (changed in code once programming is completed)
User 2 will have one of three roles.
123456789 / 123456788 / 123456787
DMS OPEN / DMS ASK / DMS CLOSED
Embed will display one of the 3 roles as
DMS ARE OPEN
YOU MUST ASKED TO DM IN #CHANNEL
DMS ARE CLOSED
This is the problem
embeduserinfo.addField("test")
test is the name of the field but there is no value
If you want to add an empty value that won’t throw an error, do this:
embeduserinfo.addField("test", "** **")
Or if you want to make it an empty name, just reverse the parameters. Otherwise you should just make it the value it should have.

Discord.js bot was working, added one extra command and everything broke. Can anyone help me figure out why?

Tried to venture in to the realm of making discord bots. Followed along with a fairly simple tutorial, tweaking it along the way to fit what I was trying to make. The bot originally worked, but I went back in to add the "Mistake" command, and suddenly it's not working. I added in console.log pretty much everywhere, trying to figure out how far everything was getting.
When I start the bot, it will spit out the "Bot Online" log. When I input a command, it will spit out the "Commands" log, but it won't register the command at all. I've tried looking for any minor typos, missing brackets, etc... but I just can't seem to figure out what's gone wrong. I'm hoping that someone here can help! Thank you!
const Discord = require('discord.js');
const config = require('./config.json');
const client = new Discord.Client();
const SQLite = require('better-sqlite3');
const sql = new SQLite('./scores.sqlite');
client.on('ready', () => {
console.log('Bot Online');
const table = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'goals';").get();
if (!table['count(*)']) {
sql.prepare('CREATE TABLE goals (id TEXT PRIMARY KEY, user TEXT, guild TEXT, goals INTEGER);').run();
sql.prepare('CREATE UNIQUE INDEX idx_goals_id ON goals (id);').run();
sql.pragma('synchronous = 1');
sql.pragma('journal_mode = wal');
}
//Statements to get and set the goal data
client.getGoals = sql.prepare('SELECT * FROM goals WHERE user = ? AND guild = ?');
client.setGoals = sql.prepare('INSERT OR REPLACE INTO goals (id, user, guild, goals) VALUES (#id, #user, #guild, #goals);');
});
client.on('message', (message) => {
if (message.author.bot) return;
let goalTotal;
if (message.guild) {
goalTotal = client.getGoals.get(message.author.id, message.guild.id);
if (!goalTotal) {
goalTotal = {
id: `${message.guild.id}-${message.author.id}`,
user: message.author.id,
guild: message.guild.id,
goals: 0,
};
}
}
if (message.content.indexOf(config.prefix) !== 0) return;
const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
console.log('Commands');
if (command === 'Goals') {
console.log('Goals');
return message.reply(`You Currently Have ${goalTotal.goals} Own Goals.`);
}
if (command === 'OwnGoal') {
console.log('Own Goal');
const user = message.mentions.users.first() || client.users.cache.get(args[0]);
if (!user) return message.reply('You must mention someone.');
let userscore = client.getGoals.get(user.id, message.guild.id);
if (!userscore) {
userscore = {
id: `${message.guild.id}-${user.id}`,
user: user.id,
guild: message.guild.id,
goals: 0,
};
}
userscore.goals++;
console.log({ userscore });
client.setGoals.run(userscore);
return message.channel.send(`${user.tag} has betrayed his team and now has a total of ${userscore.goals} own goals.`);
}
if (command === 'Mistake') {
console.log('Mistake');
const user = message.mentions.users.first() || client.users.cache.get(args[0]);
if (!user) return message.reply('You must mention someone.');
let userscore = client.getGoals.get(user.id, message.guild.id);
if (!userscore) {
return message.reply('This person has no Rocket Bot activity.');
}
if (userscore === 0) {
return message.reply('This player currently has no goals.');
}
if (userscore > 0) {
userscore.goals--;
}
console.log({ userscore });
client.setGoals.run(userscore);
return message.channel.send(`${user.tag} was falsely accused and now has a total of ${userscore.goals} own goals.`);
}
if (command === 'Leaderboard') {
console.log('Leaderboard');
const leaderboard = sql.prepare('SELECT * FROM goals WHERE guild = ? ORDER BY goals DESC;').all(message.guild.id);
const embed = new Discord.MessageEmbed()
.setTitle('Rocket Bot Leaderboard')
.setAuthor(client.user.username, client.user.avatarURL())
.setDescription('Total Goals Scored Against Own Team:')
.setFooter('Rocket Bot')
.setThumbnail('https://imgur.com/a/S9HN4bT')
.setColor('0099ff');
for (const data of leaderboard) {
embed.addFields({
name: client.users.cache.get(data.user).tag,
value: `${data.goals} goals`,
inline: true,
});
}
return message.channel.send({ embed });
}
if (command === 'RocketHelp') {
console.log('Help');
return message.reply(
'Rocket Bot Commands:' +
'\n' +
'!Goals - See How Many Goals You Have Scored Against Your Own Team' +
'\n' +
'!OwnGoal - Tag Another Player With # To Add One To Their Total' +
'\n' +
'!Mistake - Tag Another Player With # To Subtract One From Their Total' +
'\n' +
'!Leaderboard - Show The Current Leaderboard'
);
}
});
client.login(config.token);
You are improperly splitting the message content. You added g to the regex by accident.
Correct line:
const args = message.content.slice(config.prefix.length).trim().split(/ +/);
Because of improper args split, it could not find any command at all, hence no console log was invoked after Commands.

How to find a User ID from a Username in Discord.js?

I have a json file (localJSON.json) with Discord usernames (i.e. JohnDoe#1234) and need to get the User IDs from these usernames in order to have a role added. Every place I have looked online has resulted with either an 'undefined' or 'null' value for rMember. Verified that the code to add a role works when given a User ID as a string, but can't find how to get a User ID from a username.
How do I get a user's ID from their Username using Discord.js?
localJSON.json
[
{
"discordName": "JohnDoe#1234"
},
{
"discordName": "MarySue#5678"
}
]
function addRole(discordUsername, gameName, message){
var roleName = "";
//Switch statement to assign roleName to a valid guild role based on argument
var userID = discordUsername.id; //Pseudo code, Need to accomplish this
var rMember = message.guild.members.get(userID); //Needs UserID as string
var gRole = message.guild.roles.find((role) => role.name == roleName);
if (!rMember) { //if member not in server
message.channel.send(rMember + " is not in the server!");
} else { //assign role
rMember.addRole(gRole);
}
}
async run(message, args){
...
for (var i = 0; i < localJSON.length; i++) {
var currentEntry = localJSON[i];
var currrentUserName = currentEntry.discordName;
addRole(currrentUserName, args, message); //addRole(discordUsername, gameName, message);
}
}
You'll want to do
client.users.cache.find(u => u.tag === 'Someone#1234').id
Discord.js v12 uses .cache now, so you have to run find on the cache, and v12 also removes Collection#find(key, value) in favor of Collection#find(data => data.key === value).

Command for index.js

How would i create a help command that displays all the commands when people do !help as i have no idea how to do a help command in the index.js file or would it be easir to put the help would be mutch apreated. its using the dicord econmy code but it dosnt have a help command to display all the commands
const eco = require("discord-economy");
//Create the bot client
const client = new Discord.Client();
//Set the prefix and token of the bot.
const settings = {
prefix: '!',
token: 'token'
}
//Whenever someone types a message this gets activated.
//(If you use 'await' in your functions make sure you put async here)
client.on('message', async message => {
//This reads the first part of your message behind your prefix to see which command you want to use.
var command = message.content.toLowerCase().slice(settings.prefix.length).split(' ')[0];
//These are the arguments behind the commands.
var args = message.content.split(' ').slice(1);
//If the message does not start with your prefix return.
//If the user that types a message is a bot account return.
if (!message.content.startsWith(settings.prefix) || message.author.bot) return;
if (command === 'balance') {
var output = await eco.FetchBalance(message.author.id)
message.channel.send(`Hey ${message.author.tag}! You own ${output.balance} coins.`);
}
if (command === 'daily') {
var output = await eco.Daily(message.author.id)
//output.updated will tell you if the user already claimed his/her daily yes or no.
if (output.updated) {
var profile = await eco.AddToBalance(message.author.id, 100)
message.reply(`You claimed your daily coins successfully! You now own ${profile.newbalance} coins.`);
} else {
message.channel.send(`Sorry, you already claimed your daily coins!\nBut no worries, over ${output.timetowait} you can daily again!`)
}
}
if (command === 'resetdaily') {
var output = await eco.ResetDaily(message.author.id)
message.reply(output) //It will send 'Daily Reset.'
}
if (command === 'leaderboard') {
//If you use discord-economy guild based you can use the filter() function to only allow the database within your guild
//(message.author.id + message.guild.id) can be your way to store guild based id's
//filter: x => x.userid.endsWith(message.guild.id)
//If you put a mention behind the command it searches for the mentioned user in database and tells the position.
if (message.mentions.users.first()) {
var output = await eco.Leaderboard({
filter: x => x.balance > 50,
search: message.mentions.users.first().id
})
message.channel.send(`The user ${message.mentions.users.first().tag} is number ${output} on my leaderboard!`);
} else {
eco.Leaderboard({
limit: 3, //Only takes top 3 ( Totally Optional )
filter: x => x.balance > 50 //Only allows people with more than 100 balance ( Totally Optional )
}).then(async users => { //make sure it is async
if (users[0]) var firstplace = await client.fetchUser(users[0].userid) //Searches for the user object in discord for first place
if (users[1]) var secondplace = await client.fetchUser(users[1].userid) //Searches for the user object in discord for second place
if (users[2]) var thirdplace = await client.fetchUser(users[2].userid) //Searches for the user object in discord for third place
message.channel.send(`My leaderboard:
1 - ${firstplace && firstplace.tag || 'Nobody Yet'} : ${users[0] && users[0].balance || 'None'}
2 - ${secondplace && secondplace.tag || 'Nobody Yet'} : ${users[1] && users[1].balance || 'None'}
3 - ${thirdplace && thirdplace.tag || 'Nobody Yet'} : ${users[2] && users[2].balance || 'None'}`)
})
}
}
if (command === 'transfer') {
var user = message.mentions.users.first()
var amount = args[1]
if (!user) return message.reply('Reply the user you want to send money to!')
if (!amount) return message.reply('Specify the amount you want to pay!')
var output = await eco.FetchBalance(message.author.id)
if (output.balance < amount) return message.reply('You have fewer coins than the amount you want to transfer!')
var transfer = await eco.Transfer(message.author.id, user.id, amount)
message.reply(`Transfering coins successfully done!\nBalance from ${message.author.tag}: ${transfer.FromUser}\nBalance from ${user.tag}: ${transfer.ToUser}`);
}
if (command === 'coinflip') {
var flip = args[0] //Heads or Tails
var amount = args[1] //Coins to gamble
if (!flip || !['heads', 'tails'].includes(flip)) return message.reply('Please specify the flip, either heads or tails!')
if (!amount) return message.reply('Specify the amount you want to gamble!')
var output = await eco.FetchBalance(message.author.id)
if (output.balance < amount) return message.reply('You have fewer coins than the amount you want to gamble!')
var gamble = await eco.Coinflip(message.author.id, flip, amount).catch(console.error)
message.reply(`You ${gamble.output}! New balance: ${gamble.newbalance}`)
}
if (command === 'dice') {
var roll = args[0] //Should be a number between 1 and 6
var amount = args[1] //Coins to gamble
if (!roll || ![1, 2, 3, 4, 5, 6].includes(parseInt(roll))) return message.reply('Specify the roll, it should be a number between 1-6')
if (!amount) return message.reply('Specify the amount you want to gamble!')
var output = eco.FetchBalance(message.author.id)
if (output.balance < amount) return message.reply('You have fewer coins than the amount you want to gamble!')
var gamble = await eco.Dice(message.author.id, roll, amount).catch(console.error)
message.reply(`The dice rolled ${gamble.dice}. So you ${gamble.output}! New balance: ${gamble.newbalance}`)
}
if (command == 'delete') { //You want to make this command admin only!
var user = message.mentions.users.first()
if (!user) return message.reply('Please specify a user I have to delete in my database!')
if (!message.guild.me.hasPermission(`ADMINISTRATION`)) return message.reply('You need to be admin to execute this command!')
var output = await eco.Delete(user.id)
if (output.deleted == true) return message.reply('Successfully deleted the user out of the database!')
message.reply('Error: Could not find the user in database.')
}
if (command === 'work') { //I made 2 examples for this command! Both versions will work!
var output = await eco.Work(message.author.id)
//50% chance to fail and earn nothing. You earn between 1-100 coins. And you get one out of 20 random jobs.
if (output.earned == 0) return message.reply('Awh, you did not do your job well so you earned nothing!')
message.channel.send(`${message.author.username}
You worked as a \` ${output.job} \` and earned :money_with_wings: ${output.earned}
You now own :money_with_wings: ${output.balance}`)
var output = await eco.Work(message.author.id, {
failurerate: 10,
money: Math.floor(Math.random() * 500),
jobs: ['cashier', 'shopkeeper']
})
//10% chance to fail and earn nothing. You earn between 1-500 coins. And you get one of those 3 random jobs.
if (output.earned == 0) return message.reply('Awh, you did not do your job well so you earned nothing!')
message.channel.send(`${message.author.username}
You worked as a \` ${output.job} \` and earned :money_with_wings: ${output.earned}
You now own :money_with_wings: ${output.balance}`)
}
if (command === 'slots') {
var amount = args[0] //Coins to gamble
if (!amount) return message.reply('Specify the amount you want to gamble!')
var output = await eco.FetchBalance(message.author.id)
if (output.balance < amount) return message.reply('You have fewer coins than the amount you want to gamble!')
var gamble = await eco.Slots(message.author.id, amount, {
width: 3,
height: 1
}).catch(console.error)
message.channel.send(gamble.grid)//Grid checks for a 100% match vertical or horizontal.
message.reply(`You ${gamble.output}! New balance: ${gamble.newbalance}`)
}
});
//Your secret token to log the bot in. (never show this to anyone!)
client.login(settings.token) ```
The easiest way to do it would be to add something like this
if (command === 'help') {
message.reply('here are my commands: commamd1 commamd2')
}
however, you could use an embed to make it look nicer, see here fore some info about them

Categories