Is there a way to compile this into a smaller segment of code? - discord.js

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

Related

discord js I need to fetch and delete messages more than discord limit (100) allows

let purgingCounter = splitMsg[1];
function purging() {
client.channels.cache.get(channelTarget).messages.fetch({ limit: [1]})
.then(data => {
let messageArr = [...data];
console.log(messageArr[0][1]);
console.log(`Second log ${messageArr[0][1].id}`);
client.channels.cache.get(channelTarget).messages.delete(messageArr[0][1].id);
console.log(`purged`);
purgingCounter-=1;
})
.then(() => {
if (purgingCounter>0) {
purging();
}
});
};
purging();
Once deleted I want to check if user wanted to delete more than set limit and repeat the function (because discord has a limit of 100), but it gets called twice and ends up crashing after deleting one message.
async function purging (counter) {
let data = await client.channels.cache.get(channelTarget).messages.fetch({ limit: [100]})
let messageArr = [...data];
for (let i=0; i<messageArr.length; i++) {
console.log(`Ids purging: ${messageArr[i][1].id}`);
await client.channels.cache.get(channelTarget).messages.delete(messageArr[i][1].id);
counter-=1;
if (counter<=0) {
return;
}
};
//Check if user wanted to delete more than limit, Timeout makes sure it's the last bit of code to execute
setTimeout(() => {
console.log(`calling back ${counter}`);
if (counter>0) {
purging(counter);
} else { return };
}, 1);
}
purging(splitMsg[1]);
basically this is what I wanted, it works, it deletes messages over limit and doesn't delete more than asked.

Setting a timeout to delete a message embed on discord.js

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'm trying to make my bot send messages to a specific channel by using channel id

This is the code i used:
bot.on("message", function (message) {
if (message.content == '.shift') {
const channel01 = bot.channels.cache.find(channel => channel.id === "ChannelIDhere")
channel01.send('Text');
}
});
However it doesn't work for me, Most likely it is Outdated, after all the reference i found is a year ago, or i simply made a mistake.
Edit:
client.on('msg', msg => {
if (msg.content === '.go') {
const channel01 = client.channels.cache.get("872654795364765756");
channel01.send('Text');
}
});

Discord Votemute Bot

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

How to make a bot that deletes a message and posts it in another channel based on reactions

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.

Resources