Discord bot send birthday message - node.js

I have made a Discord bot and I want it to be able to check the current date, and if current date is any of the users birthday, then it'll tag them and say happy birthday. I have tried using Node.js' Date, like
if(Date === "this or that")
but that didn't seem to work. So what I need help with is:
Checking the current date (like run a check each day or something)
send a message at that current date
I'll probably just hardcode all the birthdays in since we're not that many (I know that's not good practice, but I just want it working for now, I can polish it later)
If anyone could help me with that, that'd be great.
This is what my index.js file looks like (if that is relevant):
const discord = require("discord.js");
const config = require("./config.json");
const client = new discord.Client();
const prefix = '>';
const fs = require('fs');
const { time, debug } = require("console");
client.commands = new discord.Collection();
const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js'));
for(const file of commandFiles)
{
const command = require(`./commands/${file}`)
client.commands.set(command.name, command);
}
client.once('ready', () =>
{
console.log(`${client.user.username} is online`);
})
client.on('message', message =>
{
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ + /);
const command = args.shift().toLowerCase();
if(command === 'ping')
{
client.commands.get('ping').execute(message, args);
}else if(command === 'wololo')
{
client.commands.get('wololo').execute(message, args);
}
})
client.login('TOKEN')
Edit:
I realise I wrote the "if(date)" statement in "client.on('message',message =>{})", so that obviously wouldn't check unless you wrote a command at that specific time. What function would I use?

You can check the full list of Discord.js events here.
There are no built in events in Discord.js that are fired based on scheduled time.
In order to do that, you could build a time system that fires events every single day based on a timeout out or interval. Or... you could use a library, like node-cron that do this for you.
I'll try to exemplify a way you could do this using the just said node-cron.
First, you'll have to require the node-cron package, thus you can use npm just as you did with discord.js itself. So paste and execute this command on your terminal:
npm install node-cron
Unfortunately, Discord.js doesn't offer a way for you to get the birthday date of the user. So, hard coding the birthdays (as you stated that it's okay) and also, for this example, the general channel Id that you'll send the message of the congratulations, you could something like this:
const Discord = require('discord.js');
const cron = require('node-cron');
const client = new Discord.Client();
// Hard Coded Storing Birthdays in a Map
// With the key beeing the user ID
// And the value a simplified date object
const birthdays = new Map();
birthdays.set('User 1 Birthday Id', { month: 'Jan', day: 26 });
birthdays.set('User 2 Birthday Id', { month: 'Jun', day: 13 });
birthdays.set('User 3 Birthday Id', { month: 'Aug', day: 17 });
const setSchedules = () => {
// Fetch the general channel that you'll send the birthday message
const general = client.channels.cache.get('Your General Channels Id Go Here');
// For every birthday
birthdays.forEach((birthday, userId) => {
// Define the user object of the user Id
const user = client.users.cache.get(userId);
// Create a cron schedule
cron.schedule(`* * ${birthday.day} ${birthday.month} *`, () => {
general.send(`Today's ${user.toString()} birthday, congratulations!`);
});
});
};
client.on('ready', setSchedules);
client.login('Your Token Goes Here');
This is not optimized an intends to just give a general idea of how you can do it. Notice though that the client should be instantiated before you set the tasks, so I'd recommend doing it like this example and setting the schedule on ready.
Anyway, you could always use an already created and tested bot such as Birthday Bot.

Related

MemberCounter outputs wrong numbers

I‘m trying my first member counter bot on Discord. Somehow the numbers of the online, idle and dnd members aren‘t updating correct anymore. It seems that the bot is outputting old numbers.
My code:
module.exports = async (client) => {
const guild = client.guilds.cache.get('889774617349218304');
const guildMembers = await guild.members.fetch({ withPresences: true });
const onlineCount = await guildMembers.filter(member =>!member.user.bot && member.presence?.status === "online").size
setInterval(() =>{
const channel = guild.channels.cache.get('906111710706954251');
channel.setName(`🟢 ${onlineCount.toLocaleString()}`);
console.log('Updating User-Online Count');
}, 360000);
}
Looking at your code, you are repeating the process where it changes the channel name, but using the whole variable. You are not updating the guildmember variable, hence it's always the same.
You could either move everything into the setInterval function, or redefine it.
For example:
module.exports = async (client) => {
setInterval( async () =>{
const guild = client.guilds.cache.get('889774617349218304');
const guildMembers = await guild.members.fetch({ withPresences: true });
const onlineCount = await guildMembers.filter(member =>!member.user.bot && member.presence?.status === "online").size
const channel = guild.channels.cache.get('906111710706954251');
channel.setName(`🟢 ${onlineCount.toLocaleString()}`);
console.log('Updating User-Online Count');
}, 360000);
}
This way, every hour, the bot will fetch the members of the guilds again, making it accurate.

Is there a way to delete the response of a slash command [Discord.js]

My code is:
client.ws.on('INTERACTION_CREATE', async interaction => {
const command = interaction.data.name.toLowerCase();
const args = interaction.data.options;
if (command === 'test'){
console.log("Test executed")
client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 4,
data: {
content: "Check"
}
}
})
}
});
I want to delete the answer but I don't really understand how (Very new to this discord.js thing xd)
I saw this post but can't make the answer work
Can anybody please help :(
EDIT: Is it also possible to have a cooldown for a slash command?
To delete a reply to an interaction (according to Discord Developer Portal) with discord.js v12 use the following:
client.api.webhooks(client.user.id, interaction.token)
.messages("#original").delete();
Is it also possible to have a cooldown for a slash command?
Yes, it is definitely possible. It should be very similar to cooldowns for non-slash commands. Here you can take a look at this post, very simple cooldown system. Or here you have something more complex.
Here you can have a look at my simple and far from perfect example concerning cooldown system for slash commands:
const cooldowns = new Set();
client.ws.on("INTERACTION_CREATE", (interaction) => {
const userId = interaction.member.user.id;
const commandName = interaction.data.name.toLowerCase();
const cooldownId = `${commandName}_${userId}`;
const cooldownDuration = 60000; // 60 000 ms = 1 minute
if (cooldowns.has(cooldownId)) {
// There is a cooldown, notify user and return
client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 4,
data: {
content: "Wait 1 minute before typing this again!",
flags: 64, // make reply ephemeral
}
}
});
return;
}
// Create cooldown for next use
cooldowns.add(cooldownId);
setTimeout(() => { // Schedule cooldown deletion
cooldowns.delete(cooldownId);
}, cooldownDuration);
// ... Execute the command ...
});

Making a simple music bot for discord server, not working

Working on making a bot for a personal discord server, wanting it to simply join general voicechat when command "Blyat" is detected, play mp3 file, when its done to leave. Code:
var Discord = require('discord.js');
var client = new Discord.Client();
var isReady = true;
client.on('message', message => {
if (command === "Blyat") {
var VC = message.member.voiceChannel;
if (!VC) return message.reply("MESSAGE IF NOT IN A VOICE CHANNEL")
VC.join()
.then(connection => {
const dispatcher = connection.playFile('C:\Users\Wyatt\Music\soviet-anthem.mp3');
dispatcher.on("finish", end => { VC.leave() });
})
.catch(console.error);
};
});
client.login('token, not putting in code, is there in real code');
Error: "ReferenceError: command is not defined
at Client. (C:\Users\jeffofBread\Desktop\Discord Bot\main.js:6:5)"
Any help or tips will be much appreciated, haven't coded in many years and have lost any knowledge I had once held.
Your problem comes from an unidentified variable. Fortunatly that is very easy to fix. All you have to do is define command before you call it.
For this we'll splice the message content into two parts. The command and any arguments that may be included like mentions or other words. We do that with:
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
Note: The args constant is an array.
Which would make your entire onMessage event look like this:
client.on('message', message => {
const prefix = "!";
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if (command === "blyat") {
var VC = message.member.voice.channel;
if (!VC) return message.reply("MESSAGE IF NOT IN A VOICE CHANNEL")
VC.join()
.then(connection => {
const dispatcher = connection.play('C:\Users\Wyatt\Music\soviet-anthem.mp3');
dispatcher.on("finish", end => { VC.leave() });
})
.catch(console.error);
};
});

Discord Bot - Reaction Collector/Embed Edit

I am in the process of creating a Would You Rather command for my bot.
I have everything in place, except one feature I can't work out how to implement.
I would love to have it so that when someone reacts with their answer (🅰️ or 🅱️) the bot then edits the embed and puts the user who replied under their answer like this:
The code I currently have is:
case "wyr":
embed.setColor('#fc2803')
embed.setTitle('Would You Rather?')
embed.setDescription(':a: **Be able to fly** \n \n :b: **Breathe underwater**')
message.channel.send(embed).then(m => m.react('🅰️')).then(r => r.message.react('🅱️'));
You can easily implement this using the discord.js-collector package.
But if you want to make it using plaine discord.js, then you will have to listen to reactions when sending the embed, and then edit it to what you want like in the example i will give.
Simple Example Using The discord.js-collector package:
Code Here
And Live Preview Here
Simple Example Using Plaine Discord.js:
const Discord = require("discord.js");
const embed = new Discord.MessageEmbed()
.setTitle("Hello There!");
const embedtosend = await message.channel.send(embed).then(m => m.react('🅰️')).then(r => r.message.react('🅱️'));
const filter = (reaction, user) => {
return ['🅰️', '🅱️'].includes(reaction.emoji.name) && user.id === message.author.id;
};
message.awaitReactions(filter, { max: 2, time: 60000, errors: ['time'] })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '🅰️') {
const someotherembed = new Discord.MessageEmbed()
.setTitle("This Is A Different Hello There!");
embedtosend.edit(someotherembed)
} else if (reaction.emoji.name === '🅱️') {
const anotherembed = new Discord.MessageEmbed()
.setTitle("This Is A Different Embed!");
embedtosend.edit(anotherrembed)
}
});
I haven't tested this code, so it might not work...

How to get all the mentions from an user in a channel discord.js

So, I'm trying to create a simple bot that when the user writes:
!howmanypoints {user}
It should just go to a specific channel, and search how many times it was mentioned in the specific channel.
As of now, I encountered the function fetchMentions() but it seems deprecated and the API doesn't like it when a bot tries to do this..
Any input or at least a better approach for this. Maybe I'm fixated with making it work.
const Discord = require('discord.js')
const client = new Discord.Client()
client.on('message', msg => {
if (msg.content.includes('!howmanypoints') || msg.content.includes('!cuantospuntos')) {
const canal_de_share = client.channels.find('name', 'dev')
const id_user = client.user.id
client.user.fetchMentions({guild: id_user })
.then(console.log)
.catch(console.error);
}
})
ClientUser.fetchMentions() is deprecated, and only available for user accounts.
As an alternative, you could fetch all the messages of the channel and iterate over each, checking for mentions.
Example:
let mentions = 0;
const channel = client.channels.find(c => c.name === 'dev');
const userID = client.user.id;
channel.fetchMessages()
.then(messages => {
for (let message of messages) {
if (message.mentions.users.get(userID)) mentions++;
}
console.log(mentions);
})
.catch(console.error);

Resources