Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
I have some code that detects when someone enters the command role and gives them the role with the name of the first argument passed to the command (args[0]). For example, the bot would try to detect something like !role nameOfTheRole, which would give the user the role with the name nameOfTheRole.
However, the code is not working and I'm not sure why. Here is what I have mnaged to get so far:
var cmdmap = {
role: gimmerole
}
function gimmerole(member, args, message) {
var memb = message.member() //<------- ERROR
const role = memb.guild.roles.find(r => r.name == args[0])
memb.roles.add(role)
}
client.on('message', (msg) => {
var cont = msg.content,
author = msg.member,
chan = msg.channel,
guild = msg.guild
if (author.id != client.user.id && cont.startsWith(config.prefix)) {
var invoke = cont.split(' ')[0].substr(config.prefix.length),
args = cont.split(' ').slice(1)
console.log(invoke, args)
if (invoke in cmdmap) {
cmdmap[invoke](msg, args)
}
}
})
I have made a few modifications to your code:
I changed the line function gimmerole(member, args, message) { to function gimmerole(message, args) {, as in the line cmdmap[invoke](msg, args);, you are calling it with the message object and the arguments, so the message was getting assigned to member instead and message would have been undefined.
I changed message.member() to message.member, as member is a property of message, not a method.
I also changed the code that parses the message and splits it into a command and arguments so that it's a lot cleaner.
Added a sanity check (if (!role) return console.log(`The role "${args[0]}" does not exist`);) to make the bot log to the console if the role does not exist.
Changed args[0] to args.join(' ') to enable roles with spaces to be specified.
var cmdmap = {
role: gimmerole
};
function gimmerole(message, args) {
const member = message.member;
const role = message.guild.roles.cache.find(r => r.name === args.join(' '));
if (!role) return console.log(`The role "${args.join(' ')}" does not exist`);
member.roles.add(role);
}
client.on('message', (msg) => {
var cont = msg.content,
author = msg.member,
chan = msg.channel,
guild = msg.guild;
if (author.id !== client.user.id && cont.startsWith(config.prefix)) {
const [invoke, ...args] = cont.slice(config.prefix.length).trim().split(' ');
console.log(invoke, args);
if (invoke in cmdmap) {
cmdmap[invoke](msg, args);
}
}
})
There is the Discord.js Guide that you can use if you want something to follow along with. It is really helpful and detailed.
I have noticed you're improperly trying to find a role. In order to get a full roles collection, you will need to use the cache method of message.guild.roles, resulting in the line:
const roleObject = memb.guild.roles.cache.find(...);
var cmdmap = {
role: gimmerole
};
function gimmerole(message, args) {
const member = message.member;
const role = message.guild.roles.cache.find(r => r.name === args.join(' '));
if (!role) return console.log(`The role "${args.join(' ')}" does not exist`);
member.roles.add(role);
}
client.on('message', (msg) => {
var cont = msg.content,
author = msg.member,
chan = msg.channel,
guild = msg.guild;
if (author.id !== client.user.id && cont.startsWith(config.prefix)) {
const [invoke, ...args] = cont.slice(config.prefix.length).trim().split(' ');
console.log(invoke, args);
if (invoke in cmdmap) {
cmdmap[invoke](msg, args);
}
}
}
Credits to Deamon Beast
Related
EDIT: ColinD solved my problem but now the message doesn't delete and I have no idea why the message wont delete because its worked for me before with bots
Code:
const discord = require('discord.js')
const newEmbed = require('embedcord')
const randomHex = require('random-hex')
module.exports = (client, message, options) => {
let links = require('./links.json')
let foundLink = false
let banReason = (options && options.banReason) || 'Sent a phishing link.'
let logs = (options && options.logs)
let member = message.mentions.members.first()
for(var i in links) {
if(message.content.toLowerCase().includes(links[i])) foundLink = true
}
if(foundLink) {
if(message.author.hasPermission('ADMINISTRATOR'))
return
message.delete()
member.ban({reason: banReason})
const embed = newEmbed(
'**Member Banned**',
`${randomHex.generate()}`,
`Member was banend for ${options.banReason}`
)
logs.send(embed)
}
}
Your return position might be preventing anything below if from running try changing this
if (foundLink) {
if (message.author.hasPermission('ADMINISTRATOR')) return;
const embed = newEmbed(
'**Member Banned**',
`${randomHex.generate()}`,
`Member was banend for ${options.banReason}`
);
message.delete();
member.ban({
reason: banReason
});
logs.send(embed);
}
Or this if you want if/else
if (foundLink) {
if (message.author.hasPermission('ADMINISTRATOR')) {
return;
} else {
const embed = newEmbed(
'**Member Banned**',
`${randomHex.generate()}`,
`Member was banend for ${options.banReason}`
);
message.delete();
member.ban({
reason: banReason
});
logs.send(embed);
}
}
EDIT: ColinD solved my problem but now the message doesn't delete and I have no idea why the message wont delete because its worked for me before with bots
foundLink variable is unnecessary, you can move your code inside the loop.
Use message.member.hasPermission() instead of message.author.hasPermission().
Example code for v12.5.3(Message Event):
client.on('message', (message) => {
if (message.author.bot) return; // Ignore bot messages
const { member, channel, guild } = message; // Get the message author, channel, and guild
if (!member || !channel || !guild) return; // Ignore messages without a member, channel or guild
const { links } = require('./links.json'); // Get links from json file
for (let i = 0; i < links.length; i++) { // Check if the message contains a link in the links.json file
if (message.content.toLowerCase().includes(links[i])) { // If the message contains a link
if (member.hasPermission('ADMINISTRATOR')) return; // If the member has the administrator permission, don't ban them
const banReason = 'Sent a phishing link'; // Reason for the ban
message.delete(); // Delete the message
guild.member(member).ban({ reason: banReason }); // Ban the member
channel.send(`${member.displayName} has been banned for sending a phishing link.`) // Send a message to the channel
break;
}
}
})
I'm trying to check (and create, if it does not exist) the checking process works fine.
Here is a copy of my code:
var bb_admin='0';
//Check if admin_logs exists if not create it
if(message.guild.channels.cache.find(channel => channel.name === "admin_logs") === undefined && typeof message.guild.channels.cache.find(channel => channel.name === "admin_logs") == 'undefined')
{
console.log("creating");
bb_admin = message.guild.channels.create('admin_logs', {parent: bb_cat});
} else {
console.log("already exists");
bb_admin = message.guild.channels.cache.find(channel => channel.name === "admin_logs");}
console.log('bb_admin after',bb_admin);
The problem which I'm having is I need to be able to assign the channel ID to a variable once it is created before moving on.
I cannot use a .then statement as the next steps has to happen outside of this. (I'm cycling a log file and populating the row into a channel based on contents).
What appears to be happening is I'm getting a promise back, however when I change this line:
bb_admin = message.guild.channels.create('admin_logs', {parent: bb_cat})
to:
bb_admin = await message.guild.channels.create('admin_logs', {parent: bb_cat})
to wait for the response I'm given the following error message: SyntaxError: await is only valid in async functions and the top level bodies of modules
I've seen this question which seems pretty much the same as what I'm trying to achieve. but even running attempt 2 presented with the error: TypeError: Cannot read property 'create' of undefined
Any pointers where I am going wrong here, I've been going around in circles for a few days now.
Edit: Very Basic Example:
/**
* #file app.js
* #description BeerBot
* #author Beer
* #version 0.0.1
*/
// Require all needed packages and files
const { Client, MessageEmbed } = require('discord.js');
const config = require('./config.json');
const client = new Client();
// Ready event
client.on('ready', () => {
// Log when bot is ready
console.log(`${client.user.tag} is online!`);
});
// Message event
client.on('message', message => {
if (message.author.bot || !message.guild) return;
if (!message.content.startsWith("!")) return;
//Try a simple category created command
var bb_cat = message.guild.channels.cache.find(channel => channel.name === "BeerBot");
var bb_admin = 0;
//Check if admin_logs exists if not create it
if(message.guild.channels.cache.find(channel => channel.name === "admin_logs") === undefined && typeof message.guild.channels.cache.find(channel => channel.name === "admin_logs") == 'undefined')
{
//Try and create channel
console.log("creating");
bb_admin = message.guild.channels.create('admin_logs', {parent: bb_cat});
//End try and create channel
} else {
console.log("already exists");
bb_admin = await message.guild.channels.cache.find(channel => channel.name === "admin_logs");
}
//This always returns a promise
console.log('bb_admin after',bb_admin);
});
// Login into your bot with the bot token
client.login(config.client.token);
Instead of creating an async IIFE as #Viriato suggested, you should turn your current callback to an async function like in my example below.
Also, you should use a variable if you're calling message.guild.channels.cache.find() three times :) And you don't need to check if the find() method returned undefined or checking its typeof. You can simply check if the returned value is truthy.
// make the callback function async
client.on('message', async (message) => {
if (message.author.bot || !message.guild) return;
if (!message.content.startsWith('!')) return;
let adminLogsChannel = message.guild.channels.cache.find(
(channel) => channel.name === 'admin_logs',
);
// if admin_logs does not exist, create it
if (!adminLogsChannel) {
let parent = message.guild.channels.cache.find(
(channel) => channel.name === 'BeerBot',
);
adminLogsChannel = await message.guild.channels.create('admin_logs', { parent });
}
// this returns a GuildChannel now
console.log('adminLogsChannel after', adminLogsChannel);
});
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.
hello guys iam trying to make self role and nickname change command but its not working i dont know where is the problem i earn the role but name not changing can someone tell me what is wrong on my code
client.on('message', (message,member )=> {
if (message.content.toLowerCase() === '*Test') {
if(!message.channel.guild) return;
message.member.addRole(message.guild.roles.find(role => role.name === "Test"));
let member = message.member; //message.guild.members.cache.get(user.id);
let nick = "[PRO] "
// message.guild.member(r=>r.setNickname(nick + r.user.username));
member.setNickname(nick + member.user.username);
}
});
To set Discord nickname. You can use message.member.setNickname("new member") .
as example :
if you want to create #setnick [nickname] and [nickname] is your args.
and you can use this example with role for member
client.on('message', async message => {
let messageArray = message.content.split(" ");
let args = messageArray.slice(1);
var argresult = message.content.split(` `).slice(1).join(' ');
if(message.channel.type === "dm" || message.author.bot) return;
if(message.content.toLowerCase().startsWith('#setnick')) {
if(!message.guild.me.hasPermission('MANAGE_NICKNAMES')) return message.reply('I dont have Permission to do this action.!');
try {
if(!args[0]) {
message.member.setNickname(message.author.username)
} else {
message.member.setNickname(argresult, "Member wants to change nickname")
}
} catch(error) {
return console.error('[ SET_NICKNAME ] Error')
}
}
})
Users are still getting the public role regardless of the role they have
I'm sorry if the answer here is fairly obvious but I'm learning javascript as I write this bot. I'm aiming for users to be able to do !name and gain a role called "public" as long as they don't have a role listed in the code (General, Captain, etc.).
client.on('message', async message => {
if (message.channel.id === '535226845654810624'); {
if(message.content.startsWith('!name')) {
if (message.member.roles.some(role => role.name === 'General', 'Captain', 'Lieutenant', 'Sergeant', 'Corporal', 'Recruit'));
const newname = message.content.split(' ').slice(1).join(' ');
message.member.setNickname(newname);
}
else {(message.content.startsWith('!name'));} {
if(message.channel.id === '535226845654810624') {
const newname = message.content.split(' ').slice(1).join(' ');
message.member.setNickname(newname);
const newrole = message.guild.roles.find(x => x.name === 'Public');
message.member.addRole(newrole);
message.delete();
}
}
I'm sure the code is completely ugly. I'm still learning. Right now regardless of if they have the Gen/Capt/Lieutenant/etc roles they still gain the public role.
client.on('message', async message => {
if(message.channel.id === '535226845654810624') {
if (message.content.startsWith('!name')) {
const newname = message.content.split(' ').slice(1).join(' ');
message.member.setNickname(newname);
const newrole = message.guild.roles.find(x => x.name === 'Public');
message.member.addRole(newrole);
message.delete();
}
}
This is the code I had before adding in the attempt to ignore the role add if they have the other roles. I'm not sure how to change this to what I'm looking for.
Take a look at the below code, give it a try and let me know what the result is. There were several errors with your code which I'm quite surprised your editor didn't pick up (or atleast didn't error out the code), such as having a semicolon right after defining an if statement, the extra curly brackets after your else statement, etc.
Anyway, the code below checks if the command entered is !name and if so, it assigns the new nickname to the user. After that it checks if the user has any of the specified roles, and if he does not, he gets a new role 'Public'.
client.on('message', async message => {
if (message.channel.id === '535226845654810624') {
if(message.content.startsWith('!name')) {
// Users are allowed to change their nicknames no matter their roles
const newname = message.content.split(' ').slice(1).join(' ');
message.member.setNickname(newname);
// Define the roles which need to be checked
const roleNames = ['General', 'Captain', 'Lieutenant', 'Sergeant', 'Corporal', 'Recruit'];
// If the user does not have any of the roles above, assign them the role 'Public'
if (!message.member.roles.some(role => roleNames.includes(role.name))) {
const newrole = message.guild.roles.find(x => x.name === 'Public');
message.member.addRole(newrole);
message.delete();
}
}
}
});