How to store channel Id and use it/log it - discord.js

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.

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();
});

Discord.js move messages in a different Channel

I'm trying to make the t!suggestion command work on different Servers. My problem is that i used the Channel ID in the following Code, which is obviously not working on a second Server. So my thought was to exchange the Channel ID and use the Channel Name. Unfortunatley i have no idea how to do that. And therefore are my question. Is it possible to just change the Code and use the Channel Name instead of the Channel ID and would that work?
bot.on("message", async (message) => {
if (message.content.startsWith("t!suggestion")) {
var str = message.content.slice(" t!suggestion".length);
const channelToSendId = "8786607442820137466";
const embed = new Discord.MessageEmbed()
.setThumbnail("Picture")
.setAuthor("TestBot", "small picture")
.setTitle("Suggestion")
.setColor("#151515")
.addFields({ name: "Person, that suggested somenthing:", value: `<#!${message.author.id}>` }, { name: "suggestion:", value: `${str}` }, { name: "Channel:", value: `${message.channel}` })
.setTimestamp();
await bot.channels.cache
.get(channelToSendId)
.send(embed)
.then((embedMessage) => {
embedMessage.react("✅");
embedMessage.react("❌");
});
message.delete();
}
});
Using the find method will work.
Change this
bot.channels.cache.get(channelToSendId)
To this
bot.channels.cache.find(c => c.name === 'suggestions')
The get method always finds by id (that’s how discord.js sets it), but you can put a condition in find. Note that it is a function. Another problem is that this will still only work on one channel, even if the command is run in a different guild. To fix that, you should only check the current guild's channels.
message.guild.channels.cache.find(c => c.name === 'suggestions')
This will find the channel with the name suggestions (we don’t put the # in the code) and send the message there. Keep in mind you may receive an error if the channel is not found.

(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

How to add thumbnails to Discord embeds?

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

How to fetch a message from the entire guild

I would like to know how to find a message with its id from the entire guild and not just the current channel.
I have tried
message.guild.channels.fetchMessage(message_ID)
client.channels.fetchMessage(message_ID)
message.channel.guild.fetchMessage(message_ID)
message.fetchMessage(message_ID)
message.guild.fetchMessage(message_ID)
I want it to look through the entire guild and find the message by ID then send what the message has said. Also, I have tried to have it look for the channel that I want the message from but that didn't work either.
If it's possible to get more specific with the code, it should look into a channel called #qotd-suggestions with the ID of 479658126858256406 and then find the message there and then send the message's content.
Also, the message_ID part of fetchMessages gets replaced with what I say after the command so if I say !send 485088208053469204 it should send Message content: "Wow, the admins here are so lame."
There's no way to do that with a Guild method, but you can simply loop through the channels and call TextChannel.fetchMessage() for each of them.
In order to do that, you could use Collection.forEach() but that would be a little more complex if you want to work with vars, so I suggest you to convert Guild.channels to an Array with Collection.array().
Here's an example:
async function findMessage(message, ID) {
let channels = message.guild.channels.filter(c => c.type == 'text').array();
for (let current of channels) {
let target = await current.fetchMessage(ID);
if (target) return target;
}
}
You can then use this function by passing the message that triggered the command (from which you get the guild) and the ID you're looking for. It returns a Promise<Message> or, if the message is not found, Promise<undefined>. You can get the message by either using await or Promise.then():
let m = await findMessage(message, message_ID); // Message or undefined
// OR
findMessage(message, message_ID).then(m => {/* your stuff */});

Resources