When the code works, the message 'Cannot edit a message authorized by another user' appears. How can I edit the message that the bot wrote?
client.on('messageCreate', async (message) => { // When a message is created
if (message.author.bot) return;
if(message.content === '!ping') { // If the message content is "!ping"
let timecc = 10*60
await message.reply("⏳"+parseInt((timecc / 60)/60)+"h"+parseInt((timecc / 60)%60)+"m"+(timecc % 60)+"start")
var timer = setInterval(() => {
timecc -= 1
message.edit({ content: "⏳"+parseInt((timecc / 60)/60)+"h"+parseInt((timecc / 60)%60)+"m"+(timecc % 60)+"s" })
.catch(console.error);
if (timecc === 0) {
clearInterval(timer);
message.edit({ content: "⌛"+"time out" })
.catch(console.error);
}
}, 1000)
message is the message that emitted the listener, the user's message.
To reference the bot's response you must assign the promise.
const botMsg = await message.reply(...);
botMsg.edit(...)
Related
I'm made a purge command which targets a particular member and deletes the given amount. The problem is it deletes the messages correctly while on completion it throws a unknown error. Help me fix it! Here's the code and its error
const Discord = require('discord.js');
const { Permissions } = require('discord.js');
const { MessageEmbed } = require("discord.js")
module.exports = {
description: 'purge command',
run: async (client, message, args) => {
setTimeout(() => message.delete(), 3500);
if (message.member.permissions.has(Permissions.FLAGS.KICK_MEMBERS)) {
let purgeMember = message.mentions.users.first()
let amount = args[1]
if (!purgeMember) return message.channel.send("Please Mention a Member to purge").then(msg => { setTimeout(() => msg.delete(), 4000) })
if (!amount) return message.channel.send("Please provide a valid number to purge").then(msg => { setTimeout(() => msg.delete(), 4000) })
if (isNaN(amount)) return message.channel.send("Please provide a valid number to purge").then(msg => { setTimeout(() => msg.delete(), 4000) })
if (amount > 99) return message.channel.send("I can delete upto 100 messages only").then(msg => { setTimeout(() => msg.delete(), 4000) })
let AllMessages = await message.channel.messages.fetch()
let FilteredMessages = await AllMessages.filter(x => x.author.id === purgeMember.id)
let deletedMessages = 0
FilteredMessages.forEach(msg => {
if (deletedMessages >= amount) return
msg.delete()
deletedMessages++
})
} else {
message.channel.send('🛡️ | You DONT have permission to use this command!').then(msg => { setTimeout(() => msg.delete(), 5000) })
}
},
}
Error
throw new DiscordAPIError(data, res.status, request);
^
DiscordAPIError: Unknown Message
at RequestHandler.execute (D:\STUFF\BOT\Passion-Bot-V13\node_modules\discord.js\src\rest\RequestHandler.js:298:13)
V13\node_modules\discord.js\src\structures\Message.js:709:5) {
method: 'delete',
path: '/channels/886173223144792074/messages/886174452994437170',
code: 10008,
httpStatus: 404,
requestData: { json: undefined, files: [] }
}
This error is thrown for a cached message which bot is unable to delete appearently ( maybe pinned?, maybe cached but non existant?) You could just supress this error via try/catch
try {
msg.delete()
} catch(e) {}
Furthermore at the topmost part of your code there's a
setTimeout( () => message.delete(), 3500); ( waiting 3.5 seconds before deleting the first message) , when you loop through your messages it's highly likely that the particular message with the command is in the cache existing too, so either one of those would delete it.
My suggestion:
Either use try/catch in your msg.delete() within the loop
OR
Remove the timeout on the initial message.delete()
So the problem you are encountering right now is when a message doesn't exist as every DiscordAPIError: Unknown Message just means that a message is likely to be deleted.
The code:
setTimeout(() => message.delete(), 3500);
Is the error to the problem:
FilteredMessages.forEach(msg => {
if (deletedMessages >= amount) return
msg.delete()
deletedMessages++
})
If you see the msg.delete() in the middle of the forEach function, the message has already been deleted, therefore the setTimeout is rather obvious to cause a problem.
By removing setTimeout(() => message.delete(), 3500);, it'll most likely fix the problem.
In a pervious post I was having issues getting the bot to recognise reactions and the fix worked however and then changed it to react on a message that the bot says afterwards and now it isnt working again, I have tried changing the user condition so its the original command author but that didn't seem to work
So you run the code and it makes the embed perfectly and reacts to it however it doesnt recognise when you react and makes the timeout message
exports.run = async (client, message, args) => {
message.delete()
const MINUTES = 5;
const questions = [
{ answer: null, field: 'placeholdquestion' },
{ answer: null, field: 'placeholdquestion' },
{ answer: null, field: 'placeholdquestion' },
]; //to add more questions just add another line of the above code {answes: null, field: `Question Here`}
let current = 0;
const commanduser = message.author.id
// ...
// wait for the message to be sent and grab the returned message
// so we can add the message collector
const sent = await message.author.send(
`${questions[current].field}`,
);
const filter = (response) => response.author.id === message.author.id;
// send in the DM channel where the original question was sent
const collector = sent.channel.createMessageCollector(filter, {
max: questions.length,
time: MINUTES * 60 * 1000,
});
// fires every time a message is collected
collector.on('collect', (message) => {
//if (questions > 1 && questions < 10) {
// add the answer and increase the current index HERE
questions[current++].answer = message.content;
const hasMoreQuestions = current < questions.length; //change to be an imput of how many questions you want asked
if (hasMoreQuestions) {
message.author.send(
`${questions[current].field}`,
);
}
});
// fires when either times out or when reached the limit
collector.on('end', (collected, reason) => {
if (reason === 'time') {
return message.author.send(
`I'm not saying you're slow but you only answered ${collected.size} questions out of ${questions.length} in ${MINUTES} minutes. I gave up.`,
);
}
const embed = new MessageEmbed()
.setTitle("LOA Request")
.addFields(
{ name: 'placehold', value: questions[0].answer+'/10' },
{ name: 'placehold', value: questions[1].answer+'/10' },
{ name: 'placehold', value: questions[2].answer+'/10', inline: true },)
.setColor(`#1773BA`)
.setTimestamp()
.setThumbnail("https://media.discordapp.net/attachments/772915309714735205/795378037813805126/mvg_clean_2.png")
.setFooter("request by: " + message.author.tag);
;
message.channel.send(embed)
.then(function (message) {
message.react("👍")
message.react("👎")})
const filter = (reaction, user) => {
return ['👍', '👎'].includes(reaction.emoji.name) && user.id === commanduser; //changed to try and fix it didnt work as message.author.id or this
};
message.awaitReactions(filter, { max: 1, time: 60000, errors: ['time'] } )
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '👍') {
message.channel.send('you reacted with a thumbs up.');
}
else {
message.reply('you reacted with a thumbs down.');
}
})
.catch(collected => {
console.log(`After a minute, only ${collected.size} out of 4 reacted.`);
message.reply('you didn\'t react with neither a thumbs up, nor a thumbs down.');
});
});
;
}
You have a slight logic error. You need to fit the code from your second filter to the message.awaitReactions inside of your message.channel.send(embed).then(function (message)...) method. In your code, the bot is trying to check for reactions from the original message, which you already deleted (since the awaitReactions is outside the scope of your function where you send and react to the embed).
Like this:
message.channel.send(embed)
.then(function (message) {
message.react("👍")
message.react("👎")
const filter2 = (reaction, user) => {
return ['👍', '👎'].includes(reaction.emoji.name) && user.id === commanduser;
};
message.awaitReactions(filter2, { max: 1, time: 60000, errors: ['time'] })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '👍') {
message.channel.send('you reacted with a thumbs up.');
}
else {
message.reply('you reacted with a thumbs down.');
}
})
.catch(collected => {
console.log(`After a minute, only ${collected.size} out of 4 reacted.`);
message.reply('you didn\'t react with neither a thumbs up, nor a thumbs down.');
});
})
I'm trying to make it so when my bot picks up a reaction in a specific channel, it'll see if it hit 10 reactions on a specific reaction. Then it'll delete the reacted message and post it into another specific channel with a message attached to it.
Here's the code
doopliss.on('message', message => {
if (message.channel.id === "587066921422290953") {
setTimeout(function(){
message.react(message.guild.emojis.get('587070377696690177'))
}, 10)
setTimeout(function(){
message.react(message.guild.emojis.get('587071853609353256'))
}, 50)
setTimeout(function(){
message.react(message.guild.emojis.get('587070377704816640'))
}, 100)
}
});
const message = require("discord.js");
const emoji = require("discord.js");
const reaction = require("discord.js");
doopliss.on('message', message => {
if (message.channel.id === "587066921422290953") {
let limit = 2; // number of thumbsdown reactions you need
if (message.reaction.emoji.name == message.guild.emojis.get('587070377696690177')
&& reaction.count >= limit) message.reaction.message.delete();
let tcontent = message.reaction.message.content
let accept = message.guild.channels.get('587097086256873483')
accept.send(`${tcontent} \`\`\`This server suggestion has been accepted by the community! Great job! Now a staff member just needs to forward it to username.\`\`\``)
}})
Can't figure out how to do this.
Expected Result: Bot sees if post has 10 reactions, then delete it and take the same message to a different channel
Actual Result: An error occurs Cannot read 'channel' property
First I want to say that some question here like this one have what you search.
Moreover, the discord documentation and the guide provide an awaiting reactions section.
There is some other question that refer to the subject or the function used in the guide and by searching a bit you can even find question like this one which is almost the same thing as you.
However, here is a complete example of what you want to do. You can add a timer to the promise instead of just waiting. I didn't use the reaction collector because promise are a bit faster, but you can also create a management system of multiple collector , or use the client.on('messageReactionAdd').
const Discord = require('discord.js');
const config = require('./config.json');
const channelSuggestion = '<channelID>';
const channelSend = '<channelID>';
const emojiReact = '<emojiID>';
const prefixSuggestion = '!';
const reactionMax = 11;
const client = new Discord.Client();
client.on('ready', () => {
console.log('Starting!');
client.user.setActivity(config.activity);
});
client.on('message', (msg) => {
if ((msg.content[0] === prefixSuggestion) && (msg.channel.type === 'dm')){
sendSuggestion(msg);
}
});
function filter(reaction) {
return reaction.emoji.id === emojiReact;
}
function moveSuggestion(msg) {
client.channels.get(channelSend).send(msg.content)
.then(() => msg.delete()).catch(err => console.log(error));
}
function sendSuggestion(msg){
client.channels.get(channelSuggestion).send(msg.content.substr(1))
.then((newMsg) => newMsg.react(emojiReact))
.then((newMsgReaction) =>
newMsgReaction.message
.awaitReactions(filter, {max: reactionMax})//, time: 15000, errors: ['time']})
.then(collected => {
moveSuggestion(newMsgReaction.message);
})
// .catch(collected => {
// console.log(`After a minute, only ${collected.size} out of 10 reacted.`);
// })
);
}
client.login(config.token)
.then(() => console.log("We're in!"))
.catch((err) => console.log(err));
The bot will listen to dm message (I don't know how you want your bot to send the suggestion message, so I made my own way) which start with a !.
Then the bot will send a message to a specific channel, wait for N person to add a reaction, and then will send the message to another channel.
I was using something like this but i want it to look for reactions in the embed sent! not in the message
const collector = message.createReactionCollector((reaction, user) =>
user.id === message.author.id &&
reaction.emoji.name === "◀" ||
reaction.emoji.name === "▶" ||
reaction.emoji.name === "❌"
).once("collect", reaction => {
const chosen = reaction.emoji.name;
if(chosen === "◀"){
// Prev page
}else if(chosen === "▶"){
// Next page
}else{
// Stop navigating pages
}
collector.stop();
});
A RichEmbed is sent as part of a message. Therefore, when you add a reaction, it's on the message, not the embed.
See the example below which gives the appearance of reactions on an embed.
const { RichEmbed } = require('discord.js');
var embed = new RichEmbed()
.setTitle('**Test**')
.setDescription('React with the emojis.');
message.channel.send(embed)
.then(async msg => {
// Establish reaction collector
for (emoji of ['◀', '▶', '❌']) await msg.react(emoji);
})
.catch(console.error);
This is something with the const or var. I think that it won't work unless I recode it. Here is my problem:
bot.on('ready', () => {
^
ReferenceError: bot is not defined
at C:\Users\Dylan\Desktop\discord bot\app.js:7:1
at ContextifyScript.Script.runInThisContext (vm.js:50:33)
at Object.runInThisContext (vm.js:139:38)
at Module._compile (module.js:607:28)
at Object.Module._extensions..js (module.js:654:10)
at Module.load (module.js:556:32)
at tryModuleLoad (module.js:499:12)
at Function.Module._load (module.js:491:3)
at Function.Module.runMain (module.js:684:10)
at startup (bootstrap_node.js:187:16)
Here is my code:
const Discord = require('discord');
const bot = new Discord.Bot();
const fs = require('fs')
const commandsList = fs.readFileSync('Storage/commands.txt','utf8');
});
bot.on('ready', () => {
// This event will run if the bot starts, and logs in, successfully.
console.log(`Bot has started, with ${client.users.size} users, in ${client.channels.size} channels.`);
});
bot.on('message', message => {
if (message.content === '!ping') {
message.channel.send('pong');
}
});
bot.on('message', message => {
if (message.content === '!apply') {
message.channel.send('GOGLE STUFF');
}
});
bot.on('message', message => {
if (message.content === '!server') {
message.channel.send('LA');
}
});
bot.on('message', message => {
if (message.content === '!do you know dae wae') {
message.channel.send('Yes I know dae wae brother');
}
});
bot.on('message', message => {
if (message.content === 'do you have a bot?') {
message.channel.send('no');
}
});
bot.on('message', message => {
if (message.content === 'who is the owner') {
message.channel.send('FantasmicNerd, duh');
}
});
bot.on('message', message => {
if (message.content === 'can i be staff' || message.content === 'can I be staff?' || message.content === 'can i be staff?') {
message.channel.send('Application - lalalalalala');
}
});
bot.on('message', message => {
if (message.content === 'somebody touch my spaghet') {
message.channel.send('SOMEBODY TOUCH YOUR SPAGHET!');
}
});
bot.on('message', message => {
if (message.content === 'so how about that airline food') {
message.channel.send('HAAHAHAHHAHAHAHHAHAHAHAHAHHAHAHHAHAHAHAHHAHAHAAHAHAHHAHAHAHHAHAHAHAHAHHAHAHHAHAHAHAHHAHA');
}
});
bot.on('ready',() => {
console.log('Bot Launched...')
bot.user.setStatus('Online')
bot.user.setActivity('on The Magical')
});
bot.on('message', message => {
if (message.content === '?help' || message.content === '?Help') {
message.channel.send('I have messaged you the commands and prefix.');
}
});
bot.on('message', message => {
if (message.content === '?help' || message.content === '?Help') {
message.author.sendMessage(commandsList);
}
});
bot.on('ready', function() {
bot.user.setUsername("The Magical");
// THIS MUST BE THIS WAY
bot.login('NDA0NjYzNzIwNDQzMzc5NzEy.DUapFw.zjDvPkG4QxZJ1rdxDYaPZEaVpiM');
I have looked all over for answers but nothing seems to work. I end up with this in cmd prompt when I try to run it
Where you're requiring the library you need to change it to discord.js to get access to the library.
Also the library does not expose a class called "Bot" so you need change that to "Client".
I'm guessing the )}; on line 5 is supposed to be closing the ready event on line 88.
But I suggest you just stick with one ready event, so put the status and activity methods in the first ready event and remove the other ones. Also, if you've set your bot username to what you want I would remove that method, or put a check to see if the username is already set to what you want, and if it is then don't change it.
Same with all the message events as the ready ones, stick to one message event and just chain all the if statements in that one. Example:
bot.on('message', message => {
if (message.content === '!ping') {
message.channel.send('pong');
}
else if (message.content === '!apply') {
message.channel.send('GOGLE STUFF');
}
...
});
Also you need to remember what you define your variables as. In the first ready event you use client.users instead of what you have defined, which is bot.
According to discord.js API document, there is no Bot class.
Maybe what you need is
const client = new Discord.Client();
I suggest you check the document and example for your application.