Enmap ensure not creating keys itself - javascript

My code works fine if i create the database entry myself, however when I get someone else to try the entry isnt created (even though i used a .ensure to check)
Previously it created some entries automatically but im not sure what changed and then it stopped creating them, i've tried to change the code around but the only solution seems to be creating the entries manually.
The error usually occurs when calling the +elo command
const Discord = require('discord.js')
const client = new Discord.Client()
const Enmap = require("enmap");
client.elo = new Enmap({name: "elo"});
gameVar = 0;
client.on('ready', () => {
console.log("Connected as " + client.user.tag)
// List servers the bot is connected to
console.log("Servers:")
client.guilds.forEach((guild) => {
console.log(" - " + guild.name)
var generalChannel = client.channels.get("602976588543426596") // Replace with known channel ID
generalChannel.send("--10 Man Bot--")
generalChannel.send("To begin a game, type +join")
generalChannel.send("")
})
})
client.on('message', (receivedMessage) => {
if (receivedMessage.author == client.user) { // Prevent bot from responding to its own messages
return
}
if (receivedMessage.content.startsWith("+")) {
processCommand(receivedMessage)
}
if (receivedMessage.guild) {
client.elo.ensure(`${receivedMessage.guild.id}-${receivedMessage.author.id}`, {
user: receivedMessage.author.id,
guild: receivedMessage.guild.id,
elo: 0,
console.log("entry created")
});
}
})
function processCommand(receivedMessage) {
let fullCommand = receivedMessage.content.substr(1) // Remove the leading exclamation mark
let splitCommand = fullCommand.split(" ") // Split the message up in to pieces for each space
let primaryCommand = splitCommand[0] // The first word directly after the exclamation is the command
let arguments = splitCommand.slice(1) // All other words are arguments/parameters/options for the command
console.log("Command received: " + primaryCommand)
if (primaryCommand == "elo") {
const key = `${receivedMessage.guild.id}-${receivedMessage.author.id}`;
return receivedMessage.channel.send(`ELO: ${client.elo.get(key, "elo")}`);
}
bot_secret_token =
client.login(bot_secret_token)
Here is the error message:
C:\Users\retski\node_modules\enmap\src\index.js:945
if (!this.has(key)) throw new Err(`The key "${key}" does not exist in the enmap "${this.name}"`, 'EnmapPathError');
^
EnmapPathError: The key "546829579290017793-269522297105285121" does not exist in the enmap "elo"
at Map.[check] (C:\Users\retski\node_modules\enmap\src\index.js:945:31)
at Map.get (C:\Users\retski\node_modules\enmap\src\index.js:227:19)
at processCommand (C:\Users\retski\Desktop\10 man leffy\10man.js:69:60)
at Client.client.on (C:\Users\retski\Desktop\10 man leffy\10man.js:29:9)
at Client.emit (events.js:198:13)
at MessageCreateHandler.handle (C:\Users\retski\node_modules\discord.js\src\client\websocket\packets\handlers\MessageCreate.js:9:34)
at WebSocketPacketManager.handle (C:\Users\retski\node_modules\discord.js\src\client\websocket\packets\WebSocketPacketManager.js:105:65)
at WebSocketConnection.onPacket (C:\Users\retski\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:333:35)
at WebSocketConnection.onMessage (C:\Users\retski\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:296:17)
at WebSocket.onMessage (C:\Users\retski\node_modules\ws\lib\event-target.js:120:16)```

You are calling processCommand(receivedMessage) before the ensure.
Try it like:
client.on('message', (receivedMessage) => {
if (receivedMessage.author == client.user) { // Prevent bot from responding to its own messages
return;
}
if (receivedMessage.guild) {
client.elo.ensure(`${receivedMessage.guild.id}-${receivedMessage.author.id}`, {
user: receivedMessage.author.id,
guild: receivedMessage.guild.id,
elo: 0,
});
console.log('entry created');
}
if (receivedMessage.content.startsWith('+')) {
processCommand(receivedMessage);
}
});

Related

Why does role.permissions.remove() not work?

I tried to make a command to remove the MENTION_EVERYONE permission from all roles. It didn't work for some reason. I tried console logging which roles have the permission, and it did, but the only thing is that the permission isn't being taken away. I get no error but here is my code.
client.on('message', msg => {
if(msg.content === 'checkroleperms' && msg.author.id === 'xxxxxxxxxx') {
var roles = msg.guild.roles.cache.array()
var all = '{Placeholder}'
roles.forEach(role => {
if(role.permissions.has('MENTION_EVERYONE')) {
all+= ', ' + role.name;
//RIGHT HERE IS THE WHERE THE PROBLEM IS!!
//Changed this to msg.guild.role.cache.get(role.id).permissions.re...
role.permissions.remove('MENTION_EVERYONE');
console.log(role.name);
}
})
setTimeout(() => msg.channel.send(all), 500);
}
})
Was there something I did wrong? Also, the bot has Admin perms and is the second highest role in the server (right under me). The point is that the command is running but the perms are not being removed.
EDIT: I realized I was only modifying the array, but nothing is happening even when I get it from msg.guild.roles.cache
You were pretty close, the problem is you remove the permission but you never update the role itself.
role.permissions.remove() removes bits from these permissions and returns these bits or a new BitField if the instance is frozen. It doesn't remove or update the role's permissions though.
To apply these changes, you need to use the setPermissions() method that accepts a PermissionResolvable, like the bitfield returned from the permissions.remove() method.
It's probably also better to use roles.fetch() to make sure roles are cached.
Check the working code below:
client.on('message', async (msg) => {
if (msg.content === 'checkroleperms' && msg.author.id === 'xxxxxxxxxx') {
try {
const flag = 'MENTION_EVERYONE';
const roles = await msg.guild.roles.fetch();
const updatedRoles = [];
roles.cache.each(async (role) => {
if (role.permissions.has(flag)) {
const updatedPermissions = role.permissions.remove(flag);
await role.setPermissions(updatedPermissions.bitfield);
updatedRoles.push(role.name);
}
});
const roleList = updatedRoles.join(', ') || `No role found with \`${flag}\` flag`;
setTimeout(() => msg.channel.send(roleList), 500);
} catch (error) {
console.log(error);
}
}
});

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.

JavaScript TypeError: Cannot read property 'startsWith' of undefined - discord bot

I must start this question by saying that I have very little knowledge of javascript (I'm practiced in Java) and just wanted to make a (somewhat) simple Discord bot that would say messages at random times. I Frankensteined 2 pieces of code from various tutorials together and currently have this:
var Discord = require('discord.io');
var logger = require('winston');
var auth = require('./auth.json');
//random bot code
var randomMessage;
var randOn = false;
var responseArray = [ //add more messages here
"Ayy, lmao!",
"Say what?",
"roflmaotntpmp"
];
var prefix = "!";
var timer = [5,10]; //set min and max in seconds for random messages
// Configure logger settings
logger.remove(logger.transports.Console);
logger.add(new logger.transports.Console, {
colorize: true
});
logger.level = 'debug';
// Initialize Discord Bot
var bot = new Discord.Client({
token: auth.token,
autorun: true
});
bot.on('ready', function (evt) {
logger.info('Connected');
logger.info('Logged in as: ');
logger.info(bot.username + ' - (' + bot.id + ')');
});
bot.on('message', (msg) => {
if (msg.content.startsWith(prefix + "on")) {
if (randOn) {
msg.channel.sendMessage("Already running.");
}
else {
msg.channel.sendMessage("Random message started.")
randomMessage = setTimeout(function() {
randMsg(msg.channel);
}, 1000*timer[0]);
}
}
else if (msg.content.startsWith(prefix + "off")) {
if (randOn) {
clearTimeout(randomMessage);
msg.channel.sendMessage("Random message disabled.");
}
else {
msg.channel.sendMessage("Not running.");
}
}
});
function randomIntFromInterval(min, max) {
return Math.floor(Math.random()*(max-min+1)+min);
}
function randMsg(msgChan) {
console.log("callback");
var interval = 1000*randomIntFromInterval(timer[0],timer[1]);
var rand = randomIntFromInterval(0,responseArray.length-1);
if(responseArray[rand]) {
msgChan.sendMessage(responseArray[rand]);
}
randomMessage = setTimeout(function() {
randMsg(msgChan);
}, interval);
}
The problem is occurring in this block:
bot.on('message', (msg) => {
if (msg.content.startsWith(prefix + "on")) {
if (randOn) {
msg.channel.sendMessage("Already running.");
}
Every time I attempt to command the bot in my discord chat (!on) I get the error "TypeError: Cannot read property 'startsWith' of undefined" in Node.js/command prompt. I've tried various things to fix it (removing "content" from both msg.content... statements - no complaints but absolutely nothing happens) but... I honestly have no idea what I'm doing. I've checked every post on the internet that deals with similar things and nothing has been able to answer this. I'm hoping it's a simple syntax thing/something not declared properly... If you have some time and pity for me, please help. I know I've gotten myself into a mess but I refuse to abandon it!
Let me know what other information I can provide to help.
Your issue is, that you mix discord.js with discord.io
discord.js is object oriented where discord.io is not, so in discord.io your message is already a string!
Example discord.io message event.
bot.on('message', function(user, userID, channelID, message, event) {
if (message === "ping") {
bot.sendMessage({
to: channelID,
message: "pong"
});
}
});
Maybe jam something like if(!msg || !msg.content) return; in there to bail out if the msg object or its content property is undefined.
bot.on('message', (msg) => {
if(!msg || !msg.content) return;
if (msg.content.startsWith(prefix + "on")) {
if (randOn) {
msg.channel.sendMessage("Already running.");
}
else {
msg.channel.sendMessage("Random message started.")
randomMessage = setTimeout(function() {
randMsg(msg.channel);
}, 1000*timer[0]);
}
}
else if (msg.content.startsWith(prefix + "off")) {
if (randOn) {
clearTimeout(randomMessage);
msg.channel.sendMessage("Random message disabled.");
}
else {
msg.channel.sendMessage("Not running.");
}
}
});

Username and args connecting? \\ Discord.js

The [text] is being combined with the [username] (you can place any username where "realdonaldtrump" is. anything after that is the actual message.
I've tried numerous things, only thing I ever got to work was having trump being the default tweet and not being able to change it so it would've been >tweet [message] instead of >tweet [username] [message] but I'd like to have custom usernames. Any clue on how to remove the [username] from the [text]
Here's the code
exports.exec = async (client, message, args, level, settings, texts) => {
const user = args[0];
// Fires Error message that the command wasn't ran correctly.
if (!user) {
return client.emit('commandUsage', message, this.help);
}
// Fires Error message that the command wasn't ran correctly.
const text = args.join(" ");
// Below is a self-deletion message prior to image sending when it's fetching the actual image.
message.channel.send({
embed: {
color: 0,
description: `${message.author} Generating image.`
}
}).then(msg => {
msg.delete(5000).catch(() => { });
}).catch(e => {
});
// Above is a self-deletion message prior to image sending when it's fetching the actual image.
try {
const { body } = await snekfetch.get(`https://nekobot.xyz/api/imagegen?type=${user.toLowerCase() === "realdonaldtrump" ? "trumptweet" : "tweet"}&username=${user.startsWith("#") ? user.slice(1) : user}&text=${encodeURIComponent(text)}`);
message.channel.send("", { file: body.message });
// Below is a automatic logger
} catch (err) {
const errorlogs = client.channels.get('480735959944527886')
const embed = new discord.RichEmbed()
.setAuthor("ERROR", "https://i.imgur.com/Omg7uJV.png")
.setDescription(`${message.author} An error has occured using this command, this has automatically be logged and sent to ${client.channels.get('480735959944527886')} to be reviewed.`)
.setColor(0)
.setTimestamp()
message.channel.send({ embed });
errorlogs.send(`Error with \`$tweet\` command!\n\nError:\n\n ${err}`)
}
// Above is a automatic logger
};
You are concatenating your args to set your text variable
const text = args.join(" ");
But as args value is ["realdonaltrump", "yeeet"] in your example, it results in text having the value "realdonaldtrump yeet".
Just do as you did for the uservariable:
const text = args[1]
You might need to validate the value of the argument.
You can use string.replace method and it will replace the username with nothing:
const text = args.join(" ").replace(new RegExp(`${user}`), "")
Hope it helps!!!

Why doesn't kicking people work using discord.js

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

Categories