it is invalid and I dont know how to fix it (it is for a Discord Votemute Bot).
if(!msg.mentions.users.first()) return msg.channel.send('You need to mention somebody!'); // Check if no User was Mentioned
const voting = new Discord.RichEmbed() // Generate Voting Embed
.setColor('#42b34d')
.setFooter('Mute ' + msg.mentions.users.first().tag + ' for 10m?')
.setImage(msg.mentions.users.first().avatarURL);
const role = msg.guild.roles.find(r => r.name === 'Muted'); // Find Role
if(!role) return msg.channel.send('No Role was found, please make sure you have a muteed role!'); // Make sure there is a Role
const agree = '✅'; // Define Emojis
const disagree = '❌'; // Define Emojis
const sentEmbed = await msg.channel.send(voting); // Send Embed
const filter = (reaction, user) => (reaction.emoji.name === agree || reaction.emoji.name === disagree) && !user.bot; // Filter for Reactions
await sentEmbed.react(agree); // React
await sentEmbed.react(disagree); // React
const voteStatus = await msg.channel.send('Voting started 30 seconds left'); // Send start Message and
const collected = await sentEmbed.awaitReactions(filter, { time: 5000 }); // start Collecting Reactions
const agreed = collected.get(agree) || { count: 1 }; // Retrieve Reactions
const disagreed = collected.get(disagree) || { count : 1 }; // Retrieve Reactions
const agreed_count = agreed.count - 1 ; // Count away Bot Votes
const disagreed_count = disagreed.count - 1; // Count away Bot Votes
voteStatus.edit('Voting endet with: ' + agreed_count + agree + ' and ' + disagreed_count + disagree); // Edit message to show Outcome
if(agreed.count > disagreed.count) {
await msg.guild.member(msg.mentions.users.first()).addRole(role);
await wait(600000);
await msg.guild.member(msg.mentions.users.first()).removeRole(role);
}
else {
msg.channel.send('Mute Voting Failed :)');
}
For reasons I could not pinpoint, msg.guild.member(msg.mentions.users.first()) returns null. The way I managed to get the guild member from the mention is with:
msg.guild.fetchMember(msg.mentions.users.first())
.then(async member => {
...
});
Furthermore, there is no wait function I'm aware of in js, so I replaced that as well, leaving your code looking like this:
msg.guild.fetchMember(msg.mentions.users.first())
.then(async member => {
await member.addRole(role);
setTimeout(function () { member.removeRole(role); }, 600000);
});
Related
my function getContents results in the error:"Query was already executed: Content.find({})"
why am i getting this error? how can i fix it? i recently changed this function and this was the byproduct.
exports.getContents = asyncErrors (async (req,res,next) =>{
const contentsCount = await Content.countDocuments(); //162
const resPerPage = 9;
const apiFeatures = new APIFeatures(Content.find(),req.query).search().filter()
console.log(" api " + apiFeatures)
let contents = await apiFeatures.query;
console.log(' contentslist ' + contents)
let filteredContentCount = contents.length;
console.log(' filtered ' + filteredContentCount)
apiFeatures.pagination(resPerPage)
contents = await apiFeatures.query;
/* */
// let cont = await Content.find()
// let cont2 = await Promise.all (cont.map(async (item) =>{
// item.set('content-Count',await Content.find({categories:item._id}).countDocuments(),{strict:false});
// return item
// }))
// console.log(' cont ' + cont2)
/* */
/* check for category request
assign total amount of objects within a category to a variable/constant
if(category.req){
let contentCount = category.counter
}
*/
setTimeout(() => {
res.status(200).json({
success:true,
contentsCount,
resPerPage,
filteredContentCount,
contents
})
}, 2000);
})
I have found that it could be a call back issue with async and await. but i am lost on whether that applies here
I have a basic ticketing system for a suggestions channel.
Ideally, when a user does .exesuggest <whatever suggestion they want> (.exe is the bot prefix), I want the bot to reply that the ticket has been sent to staff, i want the bot to delete the user's message, and to delete it's own message after 5 seconds. At the same time, the bot will send a message with the suggestion's author and the suggestion itself into a staff channel.
At the moment everything is working except for the bot deleting it's own message after 5 seconds.
Here is my code:
const Discord = require("discord.js")
const channelId = '873769980729106442'
const check = '✅'
let registered = false
const registerEvent = client => {
if (registered) {
return
}
registered = true
client.on('messageReactionAdd', (reaction, user) => {
if (user.bot) {
return
}
const { message } = reaction
if (message.channel.id === channelId) {
message.delete()
}
})
}
module.exports = {
commands: ['ticket', 'suggest', 'suggestion'],
minArgs: 1,
expectedArgs: '<message>',
callback: (userMessage, arguments, text, client) => {
const { guild, member } = userMessage
registerEvent(client)
const channel = guild.channels.cache.get(channelId)
const newTicketEmbed = new Discord.MessageEmbed()
.setAuthor(userMessage.author.username)
.setTitle('Created a new ticket.')
.setDescription(`"${text}"`)
.setFooter(`Click the ${check} icon to delete this message.`)
channel.send(newTicketEmbed).then(ticketMessage => {
ticketMessage.react(check)
const replyEmbed = new Discord.MessageEmbed()
.setDescription(`<#${member.id}> Your ticket has been created! Expect a reply soon!`)
userMessage.channel.send(replyEmbed)
})
}
}
I have a working command base handler in another file that makes the command work.
I just need to know exactly how to make that bot's reply in replyEmbed to be deleted after 5 seconds.
You can use a setTimeout function to delay the <message>.delete() function from executing.
Example:
setTimeout(function() { // Setup a timer
userMessage.delete(); // Deletes the users message
ticketMessage.delete(); // Deletes the ticket message
}, 5000); // 5 seconds in milliseconds
Full example:
const Discord = require("discord.js")
const channelId = '873769980729106442'
const check = '✅'
let registered = false
const registerEvent = client => {
if (registered) return;
registered = true
client.on('messageReactionAdd', (reaction, user) => {
if (user.bot) return;
const { message } = reaction
if (message.channel.id === channelId)
message.delete()
});
}
module.exports = {
commands: ['ticket', 'suggest', 'suggestion'],
minArgs: 1,
expectedArgs: '<message>',
callback: (userMessage, arguments, text, client) => {
const { guild, member } = userMessage
registerEvent(client)
const channel = guild.channels.cache.get(channelId)
const newTicketEmbed = new Discord.MessageEmbed()
.setAuthor(userMessage.author.username)
.setTitle('Created a new ticket.')
.setDescription(`"${text}"`)
.setFooter(`Click the ${check} icon to delete this message.`)
channel.send(newTicketEmbed).then(ticketMessage => {
ticketMessage.react(check)
const replyEmbed = new Discord.MessageEmbed()
.setDescription(`<#${member.id}> Your ticket has been created! Expect a reply soon!`)
userMessage.channel.send(replyEmbed);
setTimeout(function() { // Setup a timer
userMessage.delete(); // Deletes the users message
ticketMessage.delete(); // Deletes the ticket message
}, 5000); // 5 seconds in milliseconds
});
}
}
In Discord.js v13 you have to use setTimeout.
You can implement what you want like this:
userMessage.channel.send(replyEmbed).then(msg => {
setTimeout(() => msg.delete(), 5000);
});// It will delete after 5 seconds
It might work.
Message.delete has an options argument which is an object, and you can set the timeout there (v13 doesn’t have this!):
userMessage.delete({timeout: 5000}) //deletes after 5000 ms
v13 must use setTimeout since the feature was removed
setTimeout(() => userMessage.delete(), 5000) //deletes after 5000 ms
I am writing a discord bot to ping a user at a set interval. And I want to know if there is a way to compile this to not have to copy and paste the entire script to have the same thing happen for other users.
client.on('message', message => {
if(message.content === '&ping zach forever') {
setInterval(() => {
var yourchannel = client.channels.cache.get('704506336339034115');
yourchannel.send('<#UserID>');
}, "5000");
}});
client.on('message', message => {
if(message.content === '&ping maxx forever') {
setInterval(() => {
var yourchannel = client.channels.cache.get('704506336339034115');
yourchannel.send('<#UserID>');
}, "5000");
}});
I have no experience with discord bots in particular, but as general JavaScript advice:
const users = ["zach", "maxx"];
client.on('message', message => {
const splits = message.content.split(' ');
if (splits.length === 3 && splits[0] === '&ping' && splits[2] === 'forever' && users.includes(splits[1])) {
setInterval(() => {
var yourchannel = client.channels.cache.get('704506336339034115');
yourchannel.send('<#UserID>');
}, "5000");
}
});
Simply expand the users array with the required names. You can also modify the array at runtime with .push() and .splice(). If you'd like the bot to trigger even if there is text after the command, check for splits.length >= 3 instead.
PS. As a general rule, using var is frowned upon these days. Use const for values only assigned once, and let otherwise.
Edit:
Here's a bit more fleshed out example, that includes hardcoded user ID's for each name, applies the duration (in seconds), and also includes a &stop command to stop pinging a certain person. (Code is not tested to run correctly, since I don't have a discord bot account, and don't want to make one either)
const users = new Map(Object.entries({
"zach": "UserID1",
"maxx": "UserID2"
}));
const active = new Map();
client.on('message', message => {
const splits = message.content.split(' ');
if (splits.length === 3 && splits[0] === '&ping' && users.has(splits[1])) {
const channel = client.channels.cache.get('704506336339034115');
const message = `<#${users.get(splits[1])}>`;
const time = Number(splits[2]);
if (isNaN(time) && splits[2] !== 'forever') {
// Passed a time that wasn't a number - possibly send back an error message
} else {
const id = setInterval(() => channel.send(message), 5000);
active.set(splits[1], id);
if (!isNaN(time)) setTimeout(() => clearInterval(id), time * 1000);
}
}
if (splits.length === 2 && splits[0] === '&stop') {
const id = active.get(splits[1]);
if (id) {
clearInterval(id);
active.delete(splits[1]);
}
}
});
ok so i made sure to check ids,
the user im trying to unban is banned.
the id is correct
i tried to console log what userBanned returns and it is undefined
like how?
const text = args.join(` `)
const bansCollection = await message.guild.fetchBans()
const userBanned = bansCollection.find(user => user.id == text)
if (!isNaN(text)) {
if (userBanned) {
await message.guild.members.unban(text)
message.channel.send(`<#${text}> has been unbanned`)
} else { message.channel.send(new Discord.MessageEmbed().setTitle(`**That user is not Banned!**`)) }
} else { message.channel.send(`You Need the user's ID!`) }
console.log(text , bansCollection, userBanned)}
I would fetch the audit logs nd filter them.
Example:
message.guild.fetchAuditLogs()
.then(logs => {
let ban = logs.entries.filter(e => e.action === 'MEMBER_BAN_ADD') //get all the bans
ban = ban.filter(e => e.target.id === text) //filter the bans from the user
if (!message.guild.members.cache.get(text)) return message.channel.send(`This user is not in this server.`);
if (userBanned) {
await message.guild.members.unban(text)
message.channel.send(`<#${text}> has been unbanned`);
} else {
let embed = new Discord.MessageEmbed();
embed.setTitle(`**That user is not Banned!**`);
message.channel.send(embed);
}
});
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.