How to react to a message attachment discord.js - node.js

So what I am trying to do is, my discord bot listens for attachments then takes them and sends them to a particular channel, I want it to also react it with 👍 and 👎 now I saw some solutions but they require message id and channel id, my channel id would remain the same but my message id would change every time I send an attachment how do I make it so it reacts to the attachment into that channel
My code:-
client.on("message", async message => {
message.attachments.forEach((attachment) => {
if (attachment.width && attachment.height) {
if (message.author.bot) return
let yes = attachment
const channel = client.channels.cache.find(channel => channel.name === "llllllounge")
channel.send(yes)
.then(() => attachment.react('👍'))
.then(() => attachment.react('👎'))
}
});
})
I have tried yes.react('👍') but it does not work and replies with yes.react is not a function
Would be grateful if someone helps me with this.

Channel#send returns a promise. Meaning we can use an asynchronous function in order to define the channel sending method using await (Send the message before defining it), and have our bot react to the newly sent message.
Final Code
client.on("message", message => {
message.attachments.forEach(async (attachment) => {
if (attachment.width && attachment.height) {
if (message.author.bot) return
let yes = attachment
const channel = client.channels.cache.find(channel => channel.name === "llllllounge")
const msg = await channel.send(yes)
await msg.react('👍')
msg.react('👎')
}
});
})

Related

How to send a error message in a specific channel

I want my bot to send errors and warns into my private server, but I have no idea how to do it. Also is it possible to send it in a embed? And where & who triggered the error? Thanks!
This is what I tried:
client.on("error", (e) => {
client.channels.cache.get(`825634835572719658`).send(e)
})
You can find channel by it's name as follows:
const channel = client.channels.cache.find(channel => channel.name === channelName)
channel.send(message)
Create embed message like as follows
let embed = new MessageEmbed().setTitle("This is an error").setColor(0x7dd9e8)
You should be able to combine both to send an embed message to a channel!
Alternatively, with newer discord.js versions you can also do as follows:
// The channel that you want to send the messages to
const channel = client.channels.cache.get('channel id')
client.on('message',message => {
// Ignore bots
if (message.author.bot) return
// Send the embed
const embed = new Discord.MessageEmbed()
.setDescription(message.content)
.setAuthor(message.author.tag, message.author.displayAvatarURL())
channel.send(embed).catch(console.error)
})

Discord.js V12 | How can i send a welcome message to users that has joined

I want to send a message when people join my server by my bot in specific channel like this (JUST specific server not others server that bot is joined on them!):
Welcome {USERNAME_TAG}
Invited by: {THE USER WHO INVITE THE USER}
Member count: {CHANNEL MEMBERS}
I'm a new coder - sorry for noob question
You can use the guildMemberAdd event, which emits when a member joins a guild that your bot is in.
// create the event
client.on('guildMemberAdd', (member) => {
// code..
});
The first and last requests are fairly simple. You can display the member's tag with member.user.tag, and you can get the amount of member's in the guild with member.guild.memberCount.
However, your second request, while possible, will be a bit harder to execute. I recommend reading this guide to learn more about invites and how to use them, but for now, I'll just use the code they show on their site.
const invites = {};
client.on('guildMemberAdd', (member) => {
member.guild.fetchInvites().then(async (guildInvites) => {
const ei = invites[member.guild.id];
invites[member.guild.id] = guildInvites;
const invite = guildInvites.find((i) => ei.get(i.code).uses < i.uses);
const inviter = await client.users.fetch(invite.inviter.id);
const channel = member.guild.channels.cache.get('Channel ID Here');
channel.send(
`Welcome ${member.user.tag}\nInvited by ${inviter.tag ||
'Unknown#0000'}\nMember Count: ${member.guild.memberCount}`
);
});
});
The first and third things can be done. The middle thing, I do not believe can be done. Here is the code:
// Run dotenv
require('dotenv').config();
const Discord = require('discord.js');
const client = new Discord.Client();
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('guildMemberAdd', member => {
channel = member.guild.channels.cache.get("channel id");
channel.send("Welcome " + member.displayName + "\n Member Count: " + member.guild.memberCount);
})
client.login(process.env.DISCORD_TOKEN);
There. We simply send that message with some data to a channel when someone joins.
You Can Use guildMemberAdd
client.on('guildMemberAdd', (member) => {
client.channels.cache.get("YOUR CHANNEL ID").send(`Welcome ${member} To The Server!`);
});

Cache message discord.js

I would like to make some reaction roles. But for that, I have to cache messages which were sent before the bot started. I tried it with channel.messages.fetch, but that hasn't worked so far.
My current code:
client.on('messageReactionAdd', async(reaction, user) => {
client.channels.cache.get("689034237672030230");
channel.messages.fetch('708428887612194979');
// When we receive a reaction we check if the reaction is partial or not
if (reaction.partial) {
// If the message this reaction belongs to was removed the fetching might result in an API error, which we need to handle
try {
await message.reaction.fetch();
} catch (error) {
console.log('Something went wrong when fetching the message: ', error);
// Return as `reaction.message.author` may be undefined/null
return;
}
}
// Now the message has been cached and is fully available
console.log(`${reaction.message.author}'s message "${reaction.message.id}" gained a reaction!`);
// The reaction is now also fully available and the properties will be reflected accurately:
console.log(`${reaction.count} user(s) have given the same reaction to this message!`);
});
What you have to do is first fetch the guild where the channel is in and then get the channel from the guild (so it returns a GuildChannel). Then fetch messages from there.
Full code would be:
client.on('ready', async () => {
const guild = await client.guilds.fetch('guild-id-here');
const channel = guild.channels.cache.get('channel-id-here');
const message = await channel.messages.fetch('message-id-here');
});
client.on('message', message => {
//rest of your code
});
channel.messages.fetch() is not working because channel is not defined. You need to define the first 2 lines as variables:
const channel = client.channels.cache.get("689034237672030230");
const msg = channel.messages.cache.get('708428887612194979');

New to discord.js, bot reads wrong text to verify a particular user when he joins my server

So im tryna make a little bot that verifies a particular group of users to access a reserved channel. The bot is supposed to ask a secret code, and when the answer is withing the question, the bot replies to itself and an error message is displayed. How do i fix this code?
I've tried using
if(message.author.bot){return;}
but it doesnt work for some reason welp
this is my code:
client.on('guildMemberAdd', member => {
const channel = member.guild.channels.find(ch => ch.name === 'vaayil');
channel.send("type in the secret code");
client.on('message', message =>{
if(message.author.bot){return;}
if(message.content === `secret`){
channel.send("verified");
}
if(message.content !== `secret`){
channel.send("not verified");
}
});
});
Nesting events like that is generally bad practice.
However, you can avoid doing so, and make your life coding this bot easier. In Discord.js, you can use TextChannel.awaitMessages() to wait for messages that pass a certain filter, and then do something with those messages.
Example:
const secretCode = 'sloths';
client.on('guildMemberAdd', async member => {
const channel = member.guild.channels.find(c => c.name === 'vaayil');
if (!channel) return console.log('Can\'t find channel.');
try {
await channel.send(`What\'s the secret code, ${member}?`);
const filter = m => m.author.id === member.id;
const messages = await channel.awaitMessages(filter, { max: 1 });
const message = messages.first(); // (The only message in the Collection)
if (message.content === secretCode) {
await channel.send('That\'s right!');
// Do something...
} else {
await channel.send('Nice try, but wrong.');
// Do something...
} catch(err) {
console.error(err);
}
});

Populate unpopulated reaction.users

On a messageReactionAdd event, one of the parameters is a MessageReaction. From that reaction, I do message.reaction to find the message that the reaction is from. I want to use that message to find all the reactions that the parameters user has reacted to on that message.
However, one obstacle is that when the bot restarts, it seems as though the message.reactions is not fully populated, and the data needs to be fetched. I need the users of a looped reaction, but I'm struggling on that part.
I have tried:
await message.reactions.reduce((p, c) => c.fetchUsers(), 0);
// I had thought this would of cached the users of every reaction on the message, but that did not work.
// next
message.reactions.forEach((x, y) => {
x.fetchUsers();
});
// this was also the same train of thought, but still to no avail.
What I mean by that users are not in the message.reaction.users object, I mean this:
// the bot restarts - and a reaction is added
console.log(reaction.users);
// outputs: Collection [Map] {}
// this is supposed to be populated with many users, but it's empty
// however, if I add ANY reaction again, not doing anything else
// it outputs a Collection with many users in it, which is expected
I have no idea how to do this.
Edit: relevant code
// raw.js (the raw event)
const events = {
MESSAGE_REACTION_ADD: 'messageReactionAdd',
};
const Discord = require('discord.js');
module.exports = async (client, event) => {
if (!events.hasOwnProperty(event.t)) return;
const { d: data } = event;
const user = client.users.get(data.user_id);
if (!user) return;
const channel = client.channels.get(data.channel_id);
if (!channel) return;
if (channel.messages.has(data.message_id)) return;
const message = await channel.fetchMessage(data.message_id);
const emojiKey = (data.emoji.id) ? `${data.emoji.name}:${data.emoji.id}` : data.emoji.name;
let reaction = message.reactions.get(emojiKey);
if (!reaction) {
const emoji = new Discord.Emoji(client.guilds.get(data.guild_id), data.emoji);
reaction = new Discord.MessageReaction(message, emoji, 1, data.user_id === client.user.id);
}
client.emit(events[event.t], reaction, user);
};
// messageReactionAdd.js (the messageReactionAdd event)
module.exports = async (client, reaction, user) => {
const message = reaction.message;
if (!message)
return;
//await message.reactions.reduce((p, c) => c.fetchUsers(), 0);
message.reactions.forEach((x,y) => {
x.fetchUsers();
});
reactions = await message.reactions.filter(r => r.users.has(`${user.id}`));
console.log(reactions);
};
This code is what fixed this problem for me.
// raw.js event file
await reaction.message.reactions.forEach(r => {
r.fetchUsers({before: `${reaction.message.author.id}`});
});
// emit the messageReactionAdd event
// messageReactionAdd.js event file
// the message.reactions.users should be populated, which I can use
reactions = await reaction.message.reactions.filter(r => r.users.has(`${reaction.message.author.id}`));
I had used this code in the wrong events which made no logical sense which made the results that I had thought was invalid.

Resources