I had a userinfo command in v12, but i made a fully new bot in v13 and i don't know if i can use the same code again. I tried using this:
let mem = message.mentions.members.first() || message.member
const filteredRoles = mem.roles.cache.filter(role => role.id != message.guild.id)
const listedRoles = filteredRoles.sort((a, b) => b.position - a.position).map(role => role.toString())
//...code...
.addField('Roles:', listedRoles)
Error:
C:\Users\-----\-----\-----\node_modules\discord.js\src\util\Util.js:413
if (typeof data !== 'string') throw new error(errorMessage);
^
RangeError [EMBED_FIELD_VALUE]: MessageEmbed field values must be non-empty strings.
The MessageEmbed.addField() method accepts a string as its second parameter (the field's value). Your listedRoles is an array, you can use Array.join() to convert it into a string.
.addField("Roles: ", listedRoles.join(","))
Example working code:
client.on("messageCreate", async (message) => {
if (message.author.id == client.user.id) return;
if (message.content.startsWith("!roles")) {
const member = message.mentions.members.first() || message.member;
const filteredRoles = member.roles.cache.filter(role => role.id != message.guild.id);
const listedRoles = filteredRoles.sort((a, b) => b.position - a.position).map(role => role.toString());
const embed = new Discord.MessageEmbed()
.setTitle(member.user.username)
.addField("Roles", listedRoles.join(","));
message.channel.send({embeds: [embed]});
}
});
Tested using discord.js ^13.1.0.
Related
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);
});
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
My command: it does what it has to do. I can mention a user or use his id
let args = message.content.split(' ');
if (args.length > 2) return message.channel.send('Only mention one user!');
if (!args[1]) return message.channel.send('Mention someone!');
if (args[1]) {
let member = message.guild.member(
message.mentions.members.first() || message.guild.members.cache.get(args[1])
);
let roles = member.roles.cache
.filter((r) => r.name !== '#everyone')
.map((role) => role.name)
.join('\n');
if (roles.length === 0) roles = '-';
if (member) {
let embed = new Discord.MessageEmbed()
.setColor(tesseract.Constants.COLORS.TEAL)
.setTitle('User Info')
.setThumbnail(member.user.displayAvatarURL())
.setAuthor(
`${member.user.tag} (${member.id})`,
member.user.displayAvatarURL()
)
.addField('**Username:**', `${member.user.username}`, true)
.addField('**Discriminator:**', `${member.user.discriminator}`, true)
.addField('**ID:**', `${member.user.id}`, true)
.addField('**Status:**', `${member.user.presence.status}`, true)
.addField('**Joined On:**', `${member.joinedAt.toLocaleString()}`, true)
.addField(
'**Created On:**',
`${member.user.createdAt.toLocaleString()}`,
true
)
.setDescription(roles)
.setFooter(
`© ${message.guild.me.displayName}`,
this.client.user.displayAvatarURL()
);
message.channel.send(embed);
} else {
message.channel.send(`Could not find that member`);
}
}
Now i want to add that i can search for a user outside the discord. (Bot is added to 2 discords) So i want to do the user command on the second discord and search for a user from the first discord. i get this done with client.users.cache.get('user id') but due to the roles function i get a TypeError: Cannot read property 'roles' of null. If i remove the role funcion it works fine..
How can I ignore the role function when its searching for client.users.cache.get('user id')
The error is telling you that member is null. This happens when args[1] is not a valid ID or the user is not in the guild.
Check that a valid member was supplied before getting the member's roles:
// You don't need to wrap this in a message.guild.member()
let member = message.mentions.members.first() || message.guild.members.cache.get(args[1]);
if (member) {
let roles = member.roles.cache
.filter((r) => r.name !== '#everyone')
.map((role) => role.name)
.join('\n');
// rest of code...
}
client.on("roleCreate", role => {
const channel = role.guild.channels.cache.find(ch => ch.name === "welcome");
const embed = new Discord.MessageEmbed()
.setColor("DEFAULT")
.setDescription(`A new role has been created\nPermissions List: ${role.permissions}`)
channel.send(embed)
});
I am trying out different events from the Discord.JS Docs, however, when I came across the roleCreate event, I tried it out and when I create a new role, it works. But for the role.permissions; I am not quite sure why I'm getting [object Object]. How could I possibly fix this?
Discord.JS: v12.2.0
That's because role.permissions is an object:
https://discord.js.org/#/docs/main/stable/class/Permissions
Use the .toArray() method combined with join():
client.on("roleCreate", role => {
const channel = role.guild.channels.cache.find(ch => ch.name === "welcome");
const perms = role.permissions.toArray().join("\n");
const embed = new Discord.MessageEmbed()
.setColor("DEFAULT")
.setDescription(`A new role has been created\nPermissions List:\n${perms}`)
channel.send(embed)
});
To get it from CREATE_INSTANT_INVITE into Create Instant Invite
const perms = role.permissions.toArray().map(e => {
const words = e.split("_").map(x => x[0] + x.slice(1).toLowerCase());
return words.join(" ");
}).join("\n");
I have a !!userinfo command and I am trying to get it to where I can #anyone and it shows there info how I have everything else working but then I came up to this problem here is the error.
UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'map' of undefined
I have looked it up no answer, but I did come up with something it said that it usually means that is unpopulated but I don't know how to get it in there.
const Discord = module.require("discord.js");
const fs = require("fs");
const userdata = JSON.parse(fs.readFileSync('commands/storage/userdata.json', 'utf8'));
module.exports.run = async (bot, message, args) => {
let member;
if (message.mentions.users > 0) {
member = message.mentions.user.size()
} else {
member = message.author
}
let user;
if (message.mentions.users > 0) {
user = message.mentions.user.size()
} else {
user = message.author
}
embed = new Discord.RichEmbed()
.setAuthor(message.member.username)
.setDescription("Users Info", true)
.setColor("#64FF00", true)
.addField("Full Username:", `${message.member.username}${message.member.discriminator}`, true)
.addField("ID:", message.member.id, true)
.addField("Created at:", message.member.createdAt, true)
.addField("Status:", `${user.presence.status}`, true)
.addField("Game:", `${user.presence.game}`, true)
.addField("Roles", member.roles.map(r => `${r}`).join('|'), true);
message.channel.send(embed);
}
module.exports.help = {
name: "userinfo"
}
I Would like it so I can #anyone and there info comes up
You can easily make the first part:
let member;
if (message.mentions.users > 0) {
member = message.mentions.user.size()
} else {
member = message.author
}
let user;
if (message.mentions.users > 0) {
user = message.mentions.user.size()
} else {
user = message.author
}
into:
const user = message.mentions.users.first() || message.author;
const member = message.mentions.members.first() || message.member;
if(!member) return message.channel.send('This command can only be run in a guild!')
Also you want to change the embed bit to:
let embed = new Discord.RichEmbed()
.setAuthor(user.tag)
.setDescription("Users Info", true)
.setColor("#64FF00", true)
.addField("Full Username:", user.tag , true)
.addField("ID:", user.id, true)
.addField("Created at:", user.createdAt, true)
.addField("Status:", user.presence.status , true)
.addField("Game:", user.presence.game ? user.presence.game : 'none' , true)
.addField("Roles", member.roles.map(r => `${r}`).join(' | '), true);
message.channel.send(embed);
I believe the problem lies with how you assign a value to the variable member. Adding to that, I think you have some redundant code since you have a variable member and a variable user which you give a value with the same code.
Below you can find your code which I've rewritten. Give it a go and let me know what the result is.
module.exports.run = async (bot, message, args) => {
let guildMember;
if (message.mentions.members.first()) {
guildMember = message.mentions.members.first();
} else {
guildMember = message.member;
}
// We need the User object aswell for different properties
const user = guildMember.user;
let embed = new Discord.RichEmbed()
.setAuthor(user.username)
.setDescription("Users Info", true)
.setColor("#64FF00", true)
.addField("Full Username:", `${user.username}${user.discriminator}`, true)
.addField("ID:", user.id, true)
.addField("Created at:", user.createdAt, true)
.addField("Status:", `${user.presence.status}`, true)
.addField("Game:", `${user.presence.game}`, true)
.addField("Roles", guildMember.roles.map(r => `${r}`).join('|'), true);
message.channel.send(embed);
}
This sets member to a number
member = message.mentions.user.size()
Since member is now a number, trying to access member.roles results in undefined. And since undefined does not have a .map method, you see that exception.