How to fix "Problem with Reactions (Restart bot)" - javascript

I've a problem with a reaction reply System.
I want that when a user adds a reaction, that replies to a message, except that when the bot reboots it is no longer detected by the bot.
Do you know how to fix this problem?
Here is my current code :
bot.on("messageReactionAdd", function(messageReaction, user){
if(messageReaction.message.content === "Message"){
if(user.bot){return}
messageReaction.message.reply("It works.")
}
})
bot.on("message", function(message){
if(message.content.startsWith(prefix + "test")){
message.delete()
message.member.createDM().then(m => m.send("Message").then(m => m.react("✅")))
}
}

on the latest version of discord.js, you can use the Partial Events to accomplish this.
According to the doc (https://discord.js.org/#/docs/main/master/topics/partials):
Partials allow you to receive events that contain uncached instances, providing structures that contain very minimal data. For example, if you were to receive a messageDelete event with an uncached message, normally Discord.js would discard the event. With partials, you're able to receive the event, with a Message object that contains just an ID.
What you need to do is
const Discord = require('discord.js');
// add "partials" in the bot options to enable partial events
const client = new Discord.Client({"partials": ['CHANNEL', 'MESSAGE']});
[...]
client.on("messageReactionAdd", async function(messageReaction, user){
// fetch message data if we got a partial event
if (messageReaction.message.partial) await messageReaction.message.fetch();
if(messageReaction.message.content === "Message"){
if(user.bot){return}
messageReaction.message.reply("It works.")
}
})
Doing this, you must be careful on your client.on("message", ...) calls, to avoid accessing data or method that are not available.
there is a boolean message.partial that you can use to discard partial message when you don't need them.

Related

Discord.JS Message Edit

I want to edit the message over and over again.
So I made variable
this.msgRef = await channel.send({ embeds: [embedMessage] });
If I want to edit I use
this.msgRef.edit(...)
If the bot for some reason disconnects, he will lose msgReference.
Because of that, I saved it to DB.
How to create a message again because Message (object) in Discord.JS have a private constructor?
If you want to get the message again, you can simply fetch the channel's messages every time you bot connects (on the ready event for example) like so
client.on('ready', () =>{
const messages = await channel.messages.fetch()
client.msgRef = messages.find(msg => msg.author.id === client.user.id
&& msg.embeds[0]
// Etc.. Add as many conditions to make sure you choose the right message
);
})
This way, use client.msgRef.edit(...) whenever you want.

How to send a message to another Discord server on a specific channel? [duplicate]

I'm failing to achieve something very simple. I can't send a message to a specific channel. I've browsed trough the documentation and similar threads on stack overflow.
client.channels.get().send()
does NOT work.
It is not a function.
I also do not see it as a method on the Channel class on the official documentation yet every thread I've found so far has told me to use that.
I managed to have the bot reply to a message by listening for a message and then using message.reply() but I don't want that. I want my bot to say something in a specific channel in client.on('ready')
What am I missing?
You didn't provide any code that you already tested so I will give you the code for your ready event that will work!
client.on('ready', client => {
client.channels.get('CHANNEL ID').send('Hello here!');
})
Be careful that your channel id a string.
Let me know if it worked, thank you!
2020 Jun 13 Edit:
A Discord.js update requires the cache member of channels before the get method.
If your modules are legacy the above would still work. My recent solution works changing the send line as follows.
client.channels.cache.get('CHANNEL ID').send('Hello here!')
If you are using TypeScript, you will need to cast the channel in order to use the TextChannel.send(message) method without compiler errors.
import { TextChannel } from 'discord.js';
( client.channels.cache.get('CHANNEL ID') as TextChannel ).send('Hello here!')
for v12 it would be the following:
client.on('messageCreate', message => {
client.channels.cache.get('CHANNEL ID').send('Hello here!');
})
edit: I changed it to log a message.
This will work for the newest version of node.js msg.guild.channels.cache.find(i => i.name === 'announcements').send(annEmbed)
This should work
client.channels.fetch('CHANNEL_ID')
.then(channel=>channel.send('booyah!'))
Here's how I send a message to a specific channel every time a message is deleted. This is helpful if you'd like to send the message without a channel ID.
client.on("messageDelete", (messageDelete) => {
const channel = messageDelete.guild.channels.find(ch => ch.name === 'channel name here');
channel.send(`The message : "${messageDelete.content}" by ${messageDelete.author} was deleted. Their ID is ${messageDelete.author.id}`);
});
Make sure to define it if you're not using messageDelete.

How would I go about editing a message sent by a a discord bot? But only when reacted to by a user with a certain role?

I'm trying to setup a bug report system. I have the token system and everything for it, however I need to know how to have the bot edit a message when it is reacted to by a user with a particular role, which for this sake is named 'Debugger'
The event you want to listen to is client.messageReactionAdd. Be aware, that it will not listen to non-cached messages. To listen to older messages, you must enable partials, like so:
//top of your code
const client = new Discord.Client({partials: [`MESSAGE`, `CHANNEL`, `REACTION`]});
.
.
.
This will allow you to receive events for partial messages. In order to get full message from partial, you need to fetch it:
client.on('messageReactionAdd', async msgReaction => {
let msg = msgReaction.message;
//note that messageReactionAdd event returns MessageReaction object, not Message.
//this line makes it simpler to write code.
if (msg.partial) await msg.fetch().catch();
//
//rest of your reaction handler goes here
//
});
You will be able to figure out the rest by reading the documentation.

How do I track the number of reactions on a message?

So I wanted to implement report&ban system and I decided to use an embedded message with reactions added to it. Moderator can either agree or disagree. For example once 10 moderators agree with the complaint the user mentioned in this message should be banned or kicked.
I thought of using client.on('messageReactionAdd', (messageReaction, user) => {}), but it only checks cached messages. Then I found discordjs.guide about reactions and they showed how to use client.on('raw', (event) => {}), but it's was abandoned long time ago and I didn't even found any mentions about this official Discord.js documentation. Message has .awaitReactions(filter, [options]), but I have to mark voting messages somehow and then searching them in a some kind client of method which is super complicated.
Here's what I have:
const service = client.channels.get('id');
let user = msg.mentions.users.first();
if (!user) {
msg.reply('Couldn\'t find the user!')
return 1;
}
args.shift();
let reason = args.join(' ').trim();
if (!reason) {
msg.reply('No reason to create a complaint!')
return 1;
}
msg.channel.send(`I've created and sent a user complaint about ${user.tag}!)`)
.catch((e) => console.log(e));
msg.delete();
const emb = new Discord.RichEmbed()
.setTitle('User complaint')
.addField('Who?', `**User: ${user.tag}**`)
.addField('Reason?', `**Reson: ${reason}**`)
.setColor('#ff7b00')
.setFooter('Please take action');
service.send(emb)
.then(async msg => {
await msg.react('✅')
msg.react('❌')
})
.catch(e => {
console.error()
msg.reply('Couldn\'t send a user complaint!');
return 1;
})
Is it even possible? I explained my previous plan earlier, but is there a way to make is simpler?
1. Database
You should use either message.awaitReactions(); or client.on('messageReactionAdd', ...); and fetch the message on the bot ready event.
It's a very simple process. You'd require a database to store the message ID's, channel ID and of course, server ID. After that make a small algorithm inyour ready event to go through all the messages collected from the database and use either message.awaitReactions(); or client.on('messageReactionAdd', ...); on them.
I'd suggest using message.awaitReactions(); if you decide to go with the database method.
2. Global Array (Less Recommended)
If you have a really simple bot and you can't use a database then I'd recommend having a global array storing all the message IDs and using those for the client.on('messageReactionAdd', ...); event.
You'd have to check if the ID from the message array matches the ID of the message collected in the event and then act accordingly.
This method would work well for the smaller bots, but if you have a bigger, multi-server bot, then I'd highly recommend going with the database version because this version would not work after the bot restarts.

bot.sendMessage is not a function

I'm currently making a discord bot that will send out messages. Unfortunately the messages are receiving errors such as bot.sendMessage is not a function. I'm fairly new to coding so this one has me stumped. Even any google searches have not been able to help me to the point where I can understand it.
I've tried bot.send as maybe .sendMessage is now outdated I had read somewhere I believe.
var exampleSocket = new WebSocket(dataUrl);
bot.send({to: flowChannel,message: 'Websocket connected'});
exampleSocket.onopen = function (event) {
logger.info('got to here');
The output should post in my channel that the websocket connected.
bot.send({to: flowChannel,message: 'Websocket connected'});
Client.sendMessage() was removed in Discord.js 9.0 back in 2016.
I've tried bot.send as maybe .sendMessage is now outdated I had read somewhere I believe.
TextBasedChannel.sendMessage(), TextBasedChannel.sendCode(), TextBasedChannel.sendEmbed(), TextBasedChannel.sendFile(), and TextBasedChannel.sendFiles() are all deprecated.
The equivalent of your code today is as follows...
flowChannel.send('Websocket connected')
.catch(console.error); // Catch the rejected promise in the event of an error.
Discord.js Docs (Stable)
#sendMessage is deprecated.
You need to pass 'message' through and use message.channel.send()
Channel can also be a DM.
TextChannel.sendMessage (and DMchannel.sendMessage) along with all type of sendXX functions, is deprecated.
The function TextBasedChannel.send take as argument a MessageOptions value (or directly an Attachment or RichEmbed) if you want to pass anything other than just text.
To access the send function, you need a TextChannel or a DMchannel which you can get:
In the message that triggered your function like this: client.on('messages', (msg) => {msg.channel.send('Hello')})
If you have a Guild instance: guild.channels.get('channel id') or guild.channels.find(d => d.name === '<channel name>)') (note: you'll have to check if the channel is a TextChannel and not a voice one)
with the Client.channels method, which list all of the Channels that the client is currently handling, mapped by their IDs - as long as sharding isn't being used, this will be every channel in every guild, and all DM channels

Categories