How to add thumbnails to Discord embeds? - discord.js

I am creating a Discord bot that displays player statistics from Hypixel, a Minecraft server. I am trying to add their player's avatars as well, as a thumbnail in the embeds the bot sends. To get the avatars I am using Crafatar. This is the code I am using, however, the thumbnail doesn't show up on the embed. I believe this has something to do with the fact that I am using an URL with a variable in it, as I tried with just a regular URL and it worked fine.
.setThumbnail(`https://crafatar.com/avatars/${uuid}.jpg`)
The variable uuid is declared and assigned to a value further up in my code.
EDIT 1
This is the code where I get the uuid variable from. I can't see anything wrong with it, however, I am not particularly skilled in JavaScript.
var uuid = '';
getId(args[1]).then(id => {
uuid = id;
})
getId is a function defined below, which looks like this:
function getId(playername) {
return fetch(`https://api.mojang.com/users/profiles/minecraft/${playername}`)
.then(data => data.json())
.then(player => player.id);
}
This uses the Mojang API to convert the player's display name, which is entered as a command parameter, to their UUID.

From what you've posted, it seems like the problem is from the fact that you're correctly using Promises to set the value of uuid, but you're not waiting for it to be set before setting your embed thumbnail.
You should wait for it either using Promise.then() (as you did elsewhere), or async/await.
Here's an example:
// Using .then():
getId(args[1]).then(uuid => {
let embed = new MessageEmbed()
// You have to set the thumbnail after you get the actual ID:
embed.setThumbnail(`https://crafatar.com/avatars/${uuid}.jpg`)
// You can now send the embed
})
// Using async/await:
let uuid = await getId(args[1])
let embed = new MessageEmbed()
embed.setThumbnail(`https://crafatar.com/avatars/${uuid}.jpg`)

Related

How do I fetch all reactions from a specific message? [Discord.js]

So, I want to make a command for my bot which can fetch all reactions from a given message ID and store these three categories into arrays, for each reaction:
the name of the reaction (eg. :smile:)
the users who reacted (eg. RandomUser#4654, ILikePotatoes#1639)
and how many people reacted with this emoji (eg. Count: 2)
I've tried using the ReactionCollector, but it doesn't work for reactions added prior to the event being called. I've also tried using an external module called discord-fetch-all but all it does is either sending Promise { <Pending> } or undefined when I use .then().
PS: I've already set up a command handler that takes a message ID for argument.
Thank you in advance for helping.
You can get the specific message you want to be check for reactions by using:
const messageReacted = client.channels.cache.get('channelId').messages.fetch('messageId')
Then, you can go through each reaction in the message's cached reactions by using forEach
Then, in the .forEach, you can get the emoji name by using reaction._emoji.name, the number of users who used this reaction by reaction.count and all the users who reacted on the message by fetching them: await reaction.users.fetch().
Your final code might look something like:
const messageReacted = await client.channels.cache
.get('channelId')
.messages.fetch("messageId");
messageReacted.reactions.cache.forEach(async(reaction) => {
const emojiName = reaction._emoji.name
const emojiCount = reaction.count
const reactionUsers = await reaction.users.fetch();
});

How to store channel Id and use it/log it

command(client, 'explore', (message) => {
const name = message.content.replace('!explore ', '')
message.guild.channels
.create(name, {
type: 'text',
})
.then((channel) => {
const catagoryId = '847950191108554762'
channel.setParent(catagoryId)
})
const channelId = message.guild.channels.id
console.log(channelId)
})
I'm having an issue with saving the newly created channel's id so that way when the channel is done being used instead of typing the name, I can use the id to be inputted into the deletion command. Basically creating temp. predefined or newly found channels and then being able to log the Id and then with a deletion command be able to remove it without writing a name of the channel.
const channelId = message.guild.channels.id
console.log(channelId)
this was my attempt to retrieve/store then log it. I've been trying to do this on my own but have hit a roadblock.
To get a channel’s ID, just type <Channel>.id. There are multiple ways to get a channel, here is an example:
const channelID = <Message>.channel.id;
console.log(channelID);
The above example gets the ID of the message's channel
Also, <guild>.channels.id returns undefined, since guild.channels is a collection of multiple channels, and you can’t just get the id like that. This would be useless if you are trying to get the channel ID since you would have to fetch/get the channel by ID, or use a find method, which could return the wrong channel if there are multiple channels the bot has seen that goes with your condition, so what you are trying to do, it doesn’t make much sense.

I want a discord bot send a dm to somebody by their id

if (message.content === "!test"){
client.users.cache.get('id').send('message');
console.log("message sent")
}
This method doesn't work and I wasn't able to find any other methods that worked
Is there a spelling mistake or this method is outdated?
I've actually encountered this error myself once. There are two problems you might be facing here:
The user isn't cached by discord.js yet
There isn't a DMChannel open for that user yet
To solve the first one, you have to fetch the user before doing anything with it. Remember this is a Promise, so you'll have to either await for it to complete or use .then(...).
const user = await client.users.fetch('id')
Once you've fetched your user by their ID, you can then create a DMChannel which, again, returns a promise.
const dmChannel = await user.createDM()
You can then use your channel like you normally would
dmChannel.send('Hello!')
Try to create a variable like this:
var user = client.users.cache.find(user => user.id === 'USER-ID')
And then do this:
user.send('your message')

(Discord.js) Trying to get a channel id based on the name of the channel, and post a message in it

I'm trying to set up a server with a bunch of text channels named after users so that I can read their DMs to the bot. I can't figure out how to find if a text channel with that person's tag exists already, and I'm not sure if this is the correct code to do this.
Here is the code I'm trying to use:
try{
var txtChannel = client.guilds.cache.get(dmServerID).channels.find(channel => channel.name === (mesage.author.tag.replace('#','-')) && channel.type === "text");
}
catch(e){
client.guilds.cache.get(dmServerID).channels.create(message.author.tag.replace('#', '-'), 'text');
}
txtChannel.send(message.author.tag + ": " + message.content);
After running this code, it gives me an error that reads: Cannot read property 'send' of undefined.
I would also like to know if I am able to create the text channels inside of a category.
First of all, use let over var.
The error is caused by the fact that you declare txtChannel inside the try so it is not available outside that block of code.
Also, you forgot channels.cache (if you are using discord.js v12).
Here is what the code should look like:
let txtChannel = null;
// Already get the guild from the cache since we are gonna use it a bit
const guild = client.guilds.cache.get(guildID);
// Find a text channel that includes in the name the tag of the user
txtChannel = GUILD.channels.cache.find(c => c.type === "text" && c.name.includes(message.author.tag.replace('#','-'));
// If the channel doesn't exist we create the channel, using await to wait until the channel gets successfully created
if(!txtChannel) txtChannel = await GUILD.channels.create(message.author.tag);
// At the end we send the message in the gotten / created channel
txtChannels.send("the message to send");
Note that this code needs to be inside an async function, you can read more about that here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

Can't get user avatar

I'm trying to get user's avatars for a welcome message but when someone joins it never shows it. I've tried many different methods. Here is my current code.
bot.on('guildMemberAdd', member => {
const exampleEmbed = new MessageEmbed()
.setColor('#0000FF')
.addField('Welcome!', `Welcome to the server, ${member}! Go to <#channel> for the rules, then grab some roles at <#channel>!`)
.setThumbnail(member.user.displayAvatarURL)
member.guild.channels.cache.get('693219932904751177').send(exampleEmbed);
});
All you need to do it add a () behind the .displayAvatarURL
So the line would look like this:
.setThumbnail(member.user.displayAvatarURL())

Resources