Persik
Persik

Reputation: 275

Issue with "client.fetchUser" not being able to send data

I have been making a Discord Node.JS bot for awhile now, I was working on the "unban" command, but the issue I am having is two issues, first it tries unbanning a member even if they aren't banned, and second is the biggest one, client.fetchUser(toUnban) cannot parse stuff like ".username" and ".avatarURL."

I've tried making a separate system for gathering this data (because that worked) and it could use it ONLY in the function. Not outside of it.

client.fetchUser(toUnban)
  .then(user => console.log(user.username))
  .then(user => usersname = user.username)
  .catch(console.error)
console.log(usersname)

Would print (for example)

Clichefoox

If called outside of this function, it will print nothing. If called inside it would print something. The issue is I am trying to make it so it will get the avatarURL AND username. So I do not know how to achieve both in one RichEmbed.

Full code:

const Discord = require('discord.js')
exports.run = (client, message, args) => {
  if (!message.member.hasPermission("BAN_MEMBERS") || !message.author == message.guild.owner) return message.channel.send("You don't have access to this command. :x:")
  if (!message.guild.me.hasPermission("ADMINISTRATOR")) return message.channel.send(`${message.guild.owner} did not give me permission to do this! If you are the owner, please run this command \`${client.config.PREFIX}fixserver\`!`)
  let toUnban = args[0]
  if (!toUnban) return message.channel.send("You did not give a User ID!")
  if (toUnban.includes("@")) { return message.channel.send("That is not a User ID!") }
  let reason = args.slice(1).join(" ")
  if (!reason) reason = "No reason."
  var Embed = new Discord.RichEmbed()
    .setColor('#ebe234')
    .setTimestamp()
    .setDescription(`**${client.fetchUser(toUnban).username}** has been unbanned from the server!`)
    .setFooter(`V${client.config.VERSION} | ${toUnban}`, client.user.displayAvatarURL)
    .setAuthor("Unbanned", client.fetchUser(toUnban).avatarURL)
    .addField("User", message.author.tag, true)
    .addField("Reason", reason, true)
  var cEmbed = new Discord.RichEmbed()
    .setColor('#2b2b2b')
    .setTimestamp()
    .setDescription(`**${client.fetchUser(toUnban).username}** has been unbanend.`)
    .setAuthor("Unbanned", client.fetchUser(toUnban).avatarURL)
    .addField("Reason", reason)
  try {
    message.guild.unban(toUnban, reason)
  } catch(e) {
    return message.reply("This user isn't banned!")
  }
  message.channel.send({embed: cEmbed})
  try {
    var logChannel = message.guild.channels.find(c => c.name === "bot-logs")
    logChannel.send({embed: Embed})
  } catch(e) {
    message.guild.createChannel("bot-logs", {
      type: 'text',
      permissionOverwrites: [{
        id: message.guild.id,
        deny: ['READ_MESSAGES', 'SEND_MESSAGES']
      }]
    })
    setTimeout(function(){
      var logChannel = message.guild.channels.find(c => c.name === "bot-logs")
      logChannel.send({embed: Embed})
    }, client.ping*2.5)
  }
}

The outcome that was expected is that it would understand the user's name according to Client#FetchUser it passes the "User" class, so I tried calling it as a normal User class, but instead of getting an error or output, it's just blank.

Upvotes: 2

Views: 5118

Answers (2)

Persik
Persik

Reputation: 275

Giving myself this answer for anyone else who has this issue, but Client#fetchUser is not really worth using. Instead, I am going to use

let user = client.users.get(toUnban);

Why? - Because this just isn't as much as a hassle as Client#fetchUser.

Docs on client.user and what it passes: Client#Users, it passes the class of User which can be used to fetch people by ID, which is what I'm doing. It can also be used to search by name.

Also, the method I'm going to use for checking if the member is banned before attempting unbanning them is going to look something like this:

try {
  const banList = await message.guild.fetchBans();
  const bannedUser = banList.find(user => user.id === toUnban);
  if (!bannedUser) return message.channel.send("This user is not banned!");
} catch(e) {
  console.log(e);
};

Code sample supplied from Stackoverflow

You will need to make your exports.run part into an async because it awaits guild#fetchBans due to it returning a Promise more information about Async/Awaits available here, which will look something like this:

exports.run = async (client, message, args) => {
  // your code
};

This was simply more understanding than others' I have found on the internet.

Upvotes: 0

Erty Seidohl
Erty Seidohl

Reputation: 4559

.then(user => console.log(user.username)) tells the code to take in user, print the user.username and then return the return value of console.log, which is undefined.

Try

.then(user => {
  console.log(user.username);
  return user;
}

or, more concisely

.then(user => console.log(user.username) || user)

Upvotes: 2

Related Questions